home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Chip 2002 March
/
Chip_2002-03_cd1.bin
/
zkuste
/
delphi
/
kolekce
/
d3456
/
gmprintsuite_eval.exe
/
{app}
/
GmPreview.pas
< prev
next >
Wrap
Pascal/Delphi Source File
|
2002-01-09
|
149KB
|
4,729 lines
{******************************************************************************}
{ }
{ TGmPreview 2.3 }
{ }
{ Copyright (c) 2001 Graham Murt - www.MurtSoft.com }
{ }
{ Feel free to e-mail me with any comments, suggestions, bugs or help at: }
{ }
{ graham@murtsoft.com }
{ }
{******************************************************************************}
unit GmPreview;
interface
uses
Windows, Messages, SysUtils, Classes, Controls, Forms, Graphics, GmObjects,
GmTypes, GmConst, GmStream, Dialogs;
const
// cursor values...
crZoomIn = 101;
crZoomOut = 102;
DEFAULT_ZOOM = 20;
type
// *** General Types ***
TGmPaperSize = (A3, A4, A5, A6, B5, C5, Legal, Letter, Custom);
TGmCoordsRelative = (fromPage, fromPrinterMargins, fromUserMargins, fromHeaderLine);
TGmCursor = (gmDefault, gmZoomIn, gmZoomOut);
TGmDuplexType = (gmSimplex, gmHorzDuplex, gmVertDuplex);
TGmUserAction = (None, LeftButton, RightButton);
TGmMeasurement = (GmUnits, GmPixels, GmMillimeters, GmCentimeters, GmInches);
TGmOrientation = (gmPortrait, gmLandscape);
TGmOrientationType = (gmPortraitReport, gmLandscapeReport, gmMixedOrientation);
TGmPagesPerSheet = (gmOnePage, gmTwoPage, gmFourPage);
TGmPrintColor = (gmColor, gmMonochrome);
TGmPrintQuality = (gmDraft, gmLow, gmMedium, gmHigh);
TGmDitherType = (gmNone, gmCourse, gmFine, gmLineArt, gmGrayScale);
TGmVertAlignment = (gmTop, gmMiddle, gmBottom);
TGmZoomStyle = (gmFixedZoom, gmVariableZoom);
TGmValue = class;
TGmPage = class;
TGmPrinter = class;
// *** Events ***
TBeforeLoadEvent = procedure(Sender: TObject; FileVersion: Extended; var LoadFile: Boolean) of object;
TBeforePrintPage = procedure(Sender: TObject; APage: TGmPage; PrinterHandle: THandle) of object;
TBeforeWriteStream = procedure(Sender: TObject; FileStream: TStream) of object;
TBeforeReadStream = procedure(Sender: TObject; FileStream: TStream) of object;
TFileProgressEvent = procedure(Sender: TObject; Percent: Integer) of object;
TOnPageChangeEvent = procedure(Sender: TObject; PageNum: integer) of object;
TOnPrintProgressEvent = procedure(Sender: TObject; Printed, Total: integer) of object;
TOnZoomEvent = procedure(Sender: TObject; OldZoom, NewZoom: integer) of object;
TPageMouseEvent = procedure(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: TGmValue) of object;
TPageMouseMoveEvent = procedure(Sender: TObject; Shift: TShiftState; X, Y: TGmValue) of object;
TPageOrientationChanged = procedure(Sender: TObject; PageNum: integer; NewOrientation: TGmOrientation) of object;
// *** Forward declarations ***
TGmPreview = class;
// *** TGmValue ***
TGmValue = class
private
FValue: Integer; // (GmUnits)
FOnChange: TNotifyEvent;
procedure SetAsPixels(Ppi: integer; AValue: Integer);
procedure SetAsMm(AValue: Extended);
procedure SetAsCm(AValue: Extended);
procedure SetAsInches(AValue: Extended);
function GetAsPixels(Ppi: integer): Integer;
function GetAsMm: Extended;
function GetAsCm: Extended;
function GetAsInches: Extended;
public
constructor Create;
property AsUnits: Integer read FValue write FValue;
property AsMillimeters: Extended read GetAsMm write SetAsMm;
property AsCentimeters: Extended read GetAsCm write SetAsCm;
property AsInches: Extended read GetAsInches write SetAsInches;
property AsPixels[index: integer]: Integer read GetAsPixels write SetAsPixels;
property OnChange: TNotifyEvent read FOnChange write FOnChange;
end;
TGmValueRect = class
private
FLeft : TGmValue;
FTop : TGmValue;
FRight : TGmValue;
FBottom: TGmValue;
public
constructor Create;
destructor Destroy; override;
property Left: TGmValue read FLeft write FLeft;
property Top: TGmValue read FTop write FTop;
property Right: TGmValue read FRight write FRight;
property Bottom: TGmValue read FBottom write FBottom;
end;
// *** TGmPrinter ***
TGmPrinter = class(TPersistent)
private
FPrinterBins : TStringList;
FPrinterNames : TStringList;
FPrinting : Boolean;
FPreview : TGmPreview;
FPrinterMargins: TGmValueRect;
FShowServer: Boolean;
FValue: TGmValue;
function GetCanvas: TCanvas;
function GetDitherType: TGmDitherType;
function GetDuplexType: TGmDuplexType;
function GetIndexOf(APrinter: string): integer;
function GetIsColorPrinter: Boolean;
function GetPrintColorMode: TGmPrintColor;
function GetPrinterIndex: integer;
function GetPrinters: TStrings;
function GetOffset: TPoint;
function GetOrientation: TGmOrientation;
function GetPrinterBins: TStrings;
function GetPrinterBinIndex: integer;
function GetPrinterInstalled: Boolean;
function GetPrinterMargin(index: integer): TGmValue;
function GetPrinterSelected: Boolean;
function GetTitle: string;
procedure SetDitherType(ADitherType: TGmDitherType);
procedure SetDuplexType(ADuplexType: TGmDuplexType);
procedure SetOrientation(AOrientation: TGmOrientation);
procedure SetPrinterColorMode(AColor: TGmPrintColor);
procedure SetPrinterIndex(index: integer);
procedure SetPrinterBinIndex(index: integer);
procedure SetPrintQuality(AQuality: TGmPrintQuality);
procedure SetShowServer(AValue: Boolean);
procedure SetTitle(ATitle: string);
procedure UpdatePrinterMargins;
function GetPrinterAvailableHeight: TGmValue;
function GetPrinterAvailableWidth: TGmValue;
function GetPrinterHeight: TGmValue;
function GetPrinterWidth: TGmValue;
function GetPrintQuality: TGmPrintQuality;
public
constructor Create(AOwner: TGmPreview);
destructor Destroy; override;
procedure Abort;
procedure BeginDoc(AFileName: string);
procedure EndDoc;
function GetHandle: THandle;
property PrinterWidth: TGmValue read GetPrinterWidth;
property PrinterHeight: TGmValue read GetPrinterHeight;
property AvailableWidth: TGmValue read GetPrinterAvailableWidth;
property AvailableHeight: TGmValue read GetPrinterAvailableHeight;
function PrinterPpiX: integer;
function PrinterPpiY: integer;
procedure NewPage(Orientation: TGmOrientation);
procedure ResetPrinter;
property Canvas: TCanvas read GetCanvas;
property IsColorPrinter: Boolean read GetIsColorPrinter;
property PrinterBins: TStrings read GetPrinterBins;
property PrinterMargins: TGmValueRect read FPrinterMargins;
property PrinterNames: TStrings read GetPrinters;
property PrinterSelected: Boolean read GetPrinterSelected;
property PrinterIndex: integer read GetPrinterIndex write SetPrinterIndex;
property PrinterBinIndex: integer read GetPrinterBinIndex write SetPrinterBinIndex;
property Printing: Boolean read FPrinting default False;
property IndexOf[printer: string]: integer read GetIndexOf;
property Offset: TPoint read GetOffset;
property Orientation: TGmOrientation read GetOrientation write SetOrientation;
property ShowServer: Boolean read FShowServer write SetShowServer default True;
property Title: string read GetTitle write SetTitle;
published
property DitherType: TGmDitherType read GetDitherType write SetDitherType;
property Duplex: TGmDuplexType read GetDuplexType write SetDuplexType;
property PrintColor: TGmPrintColor read GetPrintColorMode write SetPrinterColorMode;
property PrintQuality: TGmPrintQuality read GetPrintQuality write SetPrintQuality default gmMedium;
end;
// *** TPrinterDevice ***
TPrinterDevice = class
Driver, Device, Port: String;
constructor Create(ADriver, ADevice, APort: PChar);
end;
// *** TGmPage ***
{PGmPageObject = ^GmPageObject;
GmPageObject = record
PrevObj: PGmPageObject;
AObject: TGmBaseObject;
NextObj: PGmPageObject;
end;}
TGmPage = class(TList)
private
FMetafile: TMetafile;
//FCount: integer;
{FStartObject: PGmPageObject;
FObjects: PGmPageObject;}
FOrientation: TGmOrientation;
FPageNum: integer;
FPreview: TGmPreview;
FInchWidth,
FInchHeight: Extended;
//procedure Add(AObject: TGmBaseObject);
function GetObject(AIndex: integer): TGmBaseObject;
procedure SetObject(AIndex: integer; AObject: TGmBaseObject);
procedure SetOrientation(AOrientation: TGmOrientation);
public
constructor Create(APreview: TGmPreview);
destructor Destroy; override;
procedure AddObject(AObject: TGmBaseObject);
procedure Clear; {$IFNDEF VER100} override; {$ENDIF}
procedure DrawPage;//(InchWidth, InchHeight: Extended);
procedure LoadFromStream(AStream: TStream);
procedure SaveToStream(AStream: TStream);
//property Count: integer read FCount;
property Metafile: TMetafile read FMetafile write FMetafile;
property GmObject[index: integer]: TGmBaseObject read GetObject write SetObject;
property Orientation: TGmOrientation read FOrientation write SetOrientation;
property PageNum: integer read FPageNum;
end;
// *** TGmPageList ***
TGmPageList = class(TList)
private
FPreview: TGmPreview;
function GetPage(APageIndex: integer): TGmPage;
procedure Repaginate;
procedure SetPage(APageIndex: integer ;APage: TGmPage);
public
constructor Create(AOwner: TGmPreview);
destructor Destroy; override;
function AddPage: TGmPage;
procedure Clear; {$IFNDEF VER100} override; {$ENDIF}
procedure DeletePage(APage: integer);
property Page[AIndex: integer]: TGmPage read GetPage write SetPage;
end;
// *** TGmCanvas ***
TGmCanvas = class(TPersistent)
private
FBrush: TBrush;
FCoordsRelative: TGmCoordsRelative;
FCopyMode: TCopyMode;
FCurrentPos: TPoint;
FDefaultMeasurement: TGmMeasurement;
FFont: TFont;
FPage: TGmPage;
FPen: TPen;
FPreview: TGmPreview;
FSavedPen: TPen;
FSavedBrush: TBrush;
FTempMetafile: TMetafile;
FTempCanvas: TMetafileCanvas;
FValue1: TGmValue;
FValue2: TGmValue;
function GetLeft: integer;
function GetTop: integer;
procedure CanvasChanged;
procedure DrawRect(x, y, x2, y2: Extended; GmMeasurement: TGmMeasurement; RectType: TGmRectType);
protected
procedure SavePen(var Message: TMessage); message GM_SAVE_PEN;
procedure RestorePen(var Message: TMessage); message GM_RESTORE_PEN;
procedure SaveBrush(var Message: TMessage); message GM_SAVE_BRUSH;
procedure RestoreBrush(var Message: TMessage); message GM_RESTORE_BRUSH;
public
constructor Create(AOwner: TGmPreview);
destructor Destroy; override;
function GraphicHeight(AGraphic: TGraphic): TGmValue;
function GraphicWidth(AGraphic: TGraphic): TGmValue;
function TextHeight(AText: string): TGmValue;
function TextWidth(AText: string): TGmValue;
procedure Arc(x, y, x2, y2, x3, y3, x4, y4: Extended; GmMeasurement: TGmMeasurement); {$IFNDEF VER100} overload; {$ENDIF}
procedure Chord(x, y, x2, y2, x3, y3, x4, y4: Extended; GmMeasurement: TGmMeasurement); {$IFNDEF VER100} overload; {$ENDIF}
procedure Draw(x, y: Extended; AGraphic: TGraphic; Scale: Extended; GmMeasurement: TGmMeasurement); {$IFNDEF VER100} overload; {$ENDIF}
procedure Ellipse(x, y, x2, y2: Extended; GmMeasurement: TGmMeasurement); {$IFNDEF VER100} overload; {$ENDIF}
procedure FillRect(x, y, x2, y2: Extended; GmMeasurement: TGmMeasurement); {$IFNDEF VER100} overload; {$ENDIF}
procedure FloatOut(x, y, AValue: Extended; Format: string; GmMeasurement: TGmMeasurement); {$IFNDEF VER100} overload; {$ENDIF}
procedure Line(x, y, x2, y2: Extended; GmMeasurement: TGmMeasurement); {$IFNDEF VER100} overload; {$ENDIF}
procedure LineExt(x, y, x2, y2: Extended; LineWidth: Integer; GmMeasurement: TGmMeasurement); {$IFNDEF VER100} overload; {$ENDIF}
procedure LineTo(x, y: Extended; GmMeasurement: TGmMeasurement);
procedure MoveTo(x, y: Extended; GmMeasurement: TGmMeasurement);
procedure Pie(x, y, x2, y2, x3, y3, x4, y4: Extended; GmMeasurement: TGmMeasurement); {$IFNDEF VER100} overload; {$ENDIF}
{$IFNDEF VER100}
procedure Polygon(Points: array of TGmPoint; GmMeasurement: TGmMeasurement); {$IFNDEF VER100} overload; {$ENDIF}
procedure PolyLine(Points: array of TGmPoint; GmMeasurement: TGmMeasurement); {$IFNDEF VER100} overload; {$ENDIF}
procedure PolyLineTo(Points: array of TGmPoint; GmMeasurement: TGmMeasurement);
procedure PolyBezier(Points: array of TGmPoint; GmMeasurement: TGmMeasurement); {$IFNDEF VER100} overload; {$ENDIF}
procedure PolyBezierTo(Points: array of TGmPoint; GmMeasurement: TGmMeasurement);
{$ENDIF}
procedure Rectangle(x, y, x2, y2: Extended; GmMeasurement: TGmMeasurement); {$IFNDEF VER100} overload; {$ENDIF}
procedure RotateOut(x, y, Angle: Extended; AText: string; GmMeasurement: TGmMeasurement); {$IFNDEF VER100} overload; {$ENDIF}
procedure RoundRect(x, y, x2, y2, x3, y3: Extended; GmMeasurement: TGmMeasurement); {$IFNDEF VER100} overload; {$ENDIF}
procedure StretchDraw(x,y, x2, y2: Extended; AGraphic: TGraphic; GmMeasurement: TGmMeasurement); {$IFNDEF VER100} overload; {$ENDIF}
function TextBox(x, y, x2, y2: Extended; AText: string;
Alignment: TAlignment; Draw: Boolean; GmMeasurement: TGmMeasurement): Extended; {$IFNDEF VER100} overload; {$ENDIF}
function TextBoxExt(x, y, x2, y2: Extended; AText: string;
Alignment: TAlignment; VertAlignment: TGmVertAlignment; Draw: Boolean; GmMeasurement: TGmMeasurement): Extended; {$IFNDEF VER100} overload; {$ENDIF}
procedure TextExtent(AText : string; var AWidth, AHeight: TGmValue);
{$IFNDEF BCB}
procedure TextOut(x, y: Extended; AText: string; GmMeasurement: TGmMeasurement); {$IFNDEF VER100} overload; {$ENDIF}
{$ENDIF}
procedure TextOutLeft(x, y: Extended; AText: string; GmMeasurement: TGmMeasurement); {$IFNDEF VER100} overload; {$ENDIF}
procedure TextOutRight(x, y: Extended; AText: string; GmMeasurement: TGmMeasurement); {$IFNDEF VER100} overload; {$ENDIF}
{ overloaded methods }
{$IFNDEF VER100}
procedure Ellipse(ARect: TGmRect; GmMeasurement: TGmMeasurement); overload;
procedure FillRect(ARect: TGmRect; GmMeasurement: TGmMeasurement); overload;
procedure Line(ARect: TGmRect; GmMeasurement: TGmMeasurement); overload;
procedure LineExt(ARect: TGmRect; LineWidth: integer; GmMeasurement: TGmMeasurement); overload;
procedure Rectangle(ARect: TGmRect; GmMeasurement: TGmMeasurement); overload;
procedure RoundRect(ARect: TGmRect; X3, Y3: Extended; GmMeasurement: TGmMeasurement); overload;
function TextBox(ARect: TGmRect; AText: string;
Alignment: TAlignment; Draw: Boolean; GmMeasurement: TGmMeasurement): Extended; overload;
function TextBoxExt(ARect: TGmRect; AText: string;
Alignment: TAlignment; VertAlignment: TGmVertAlignment; Draw: Boolean; GmMeasurement: TGmMeasurement): Extended; overload;
// methods which use the default measurement...
procedure Arc(x1, y1, x2, y2, x3, y3, x4, y4: Extended); overload;
procedure Chord(x1, Y1, x2, y2, x3, y3, x4, y4: Extended); overload;
procedure Draw(X,Y: double; AGraphic: TGraphic; Scale: Extended); overload;
procedure Ellipse(X, Y, x2, y2: Extended); overload;
procedure FillRect(X, Y, x2, y2: Extended); overload;
procedure FloatOut(X, Y, AValue: Extended; Format: string); overload;
procedure Line(X, Y, x2, y2: Extended); overload;
procedure LineExt(X, Y, x2, y2: Extended; LineWidth: Integer); overload;
procedure Pie(x, Y, x2, y2, x3, y3, x4, y4: Extended); overload;
procedure RotateOut(X, Y, Angle: Extended; AText: string); overload;
{$IFNDEF BCB}
procedure TextOut(X, Y: Extended; AText: string); overload;
{$ENDIF}
procedure TextOutLeft(X, Y: Extended; AText: string); overload;
procedure TextOutRight(X, Y: Extended; AText: string); overload;
function TextBox(X, Y, x2, y2: Extended; AText: string;
Alignment: TAlignment; Draw: Boolean): Extended; overload;
function TextBoxExt(X, Y, x2, y2: Extended; AText: string;
Alignment: TAlignment; VertAlignment: TGmVertAlignment; Draw: Boolean): Extended; overload;
procedure Rectangle(X, Y, x2, y2: Extended); overload;
procedure RoundRect(X, Y, x2, y2, x3, y3: Extended); overload;
procedure Polygon(Points: array of TGmPoint); overload;
procedure PolyLine(Points: array of TGmPoint); overload;
procedure PolyBezier(Points: array of TGmPoint); overload;
procedure StretchDraw(X,Y, x2, y2: Extended; AGraphic: TGraphic); overload;
{$ENDIF}
property Brush: TBrush read FBrush write FBrush;
property CopyMode: TCopyMode read FCopyMode write FCopyMode default cmSrcCopy;
property CoordsRelativeTo: TGmCoordsRelative read FCoordsRelative write FCoordsRelative default fromPage;
property DefaultMeasurement: TGmMeasurement read FDefaultMeasurement write FDefaultMeasurement default GmMillimeters;
property Font: TFont read FFont write FFont;
property Page: TGmPage read FPage write FPage;
property Pen: TPen read FPen write FPen;
end;
// *** TGmMargins ***
TGmPageImage = class;
TGmMargins = class(TPersistent)
private
FClipMargins: Boolean;
FPaintBox: TGmPageImage;
FBottom: TGmValue;
FLeft: TGmValue;
FPen: TPen;
FRight: TGmValue;
FTop: TGmValue;
FPreview: TGmPreview;
FPrinterPen: TPen;
FShowPrintMargins: Boolean;
FVisible: Boolean;
procedure PenChange(Sender: TObject);
procedure SetClipMargins(AValue: Boolean);
procedure SetShowPrinterMargins(AValue: Boolean);
procedure SetVisible(AValue: Boolean);
procedure MarginsChanged(AObject: TObject);
public
constructor Create(AOwner: TGmPreview);
destructor Destroy; override;
function AreMarginsValid: Boolean;
procedure Assign(Source: TPersistent); override;
procedure LoadFromStream(AStream: TStream);
procedure SaveToStream(AStream: TStream);
procedure UsePrinterMargins;
property Bottom: TGmValue read FBottom write FBottom;
property Left: TGmValue read FLeft write FLeft;
property Right: TGmValue read FRight write FRight;
property Top: TGmValue read FTop write FTop;
published
property ClipMargins: Boolean read FClipMargins write SetClipMargins default False;
property Pen: TPen read FPen write FPen;
property PrinterMarginPen: TPen read FPrinterPen write FPrinterPen;
property ShowPrinterMargins: Boolean read FShowPrintMargins write SetShowPrinterMargins default False;
property Visible: Boolean read FVisible write SetVisible default False;
end;
// *** TGmPageImage ***
TGmPageImage = class(TGmCustomPage)
private
FValue1: TGmValue;
FValue2: TGmValue;
FMargins: TObject;
FHeightInches: Extended;
FWidthInches: Extended;
FPageHeight: integer;
FPageWidth: integer;
FScale: Extended;
procedure SetHeightInches(AValue: Extended);
procedure SetWidthInches(AValue: Extended);
procedure RecalculateSize;
procedure SetScale(AScale: Extended);
protected
procedure CMMouseLeave (var Message: TMessage); message CM_MOUSELEAVE;
procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
procedure MouseMove(Shift: TShiftState; X, Y: Integer); override;
procedure Paint; override;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
property Margins: TObject write FMargins;
property HeightInches: Extended read FHeightInches write SetHeightInches;
property WidthInches: Extended read FWidthInches write SetWidthInches;
property Scale: Extended read FScale write SetScale;
end;
// *** TGmHeaderFooterCaption ***
TGmHeaderFooter = class;
TGmHeaderFooterCaption = class(TPersistent)
private
FCaption: string;
FFont: TFont;
FHeaderFooter: TGmHeaderFooter;
procedure FontChange(Sender: TObject);
procedure SetCaption(ACaption: string);
procedure SetFont(AFont: TFont);
public
constructor Create(AOwner: TGmHeaderFooter);
destructor Destroy; override;
procedure Assign(Source: TPersistent); override;
procedure LoadFromStream(AStream: TStream);
procedure SaveToStream(AStream: TStream);
published
property Caption: string read FCaption write SetCaption;
property Font: TFont read FFont write SetFont;
end;
// *** TGmHeaderFooter ***
THeaderFooterState = (hfIdle, hfCreating, hfDestroying, hfDrawing, hfPrinting);
TGmHeaderFooter = class(TPersistent)
private
FCanvas: TGmCanvas;
FCaptionLeft : TGmHeaderFooterCaption;
FCaptionRight : TGmHeaderFooterCaption;
FCaptionCenter: TGmHeaderFooterCaption;
FPen: TPen;
FPreview: TGmPreview;
FShowLine: Boolean;
FState: THeaderFooterState;
FVisible: Boolean;
FHeight: TGmValue;
procedure SetCaptionLeft(ACaption: string);
procedure SetCaptionCenter(ACaption: string);
procedure SetCaptionRight(ACaption: string);
procedure SetCaptionLeftFont(AFont: TFont);
procedure SetCaptionCenterFont(AFont: TFont);
procedure SetCaptionRightFont(AFont: TFont);
function GetCaptionLeft: string;
function GetCaptionCenter: string;
function GetCaptionRight: string;
function GetCaptionLeftFont: TFont;
function GetCaptionCenterFont: TFont;
function GetCaptionRightFont: TFont;
procedure PenChange(Sender: TObject);
procedure SetPen(APen: TPen);
procedure SetShowLine(AValue: Boolean);
procedure SetVisible(AVisible: Boolean);
function GetCaptionHeight(ACanvas: TCanvas; ACaption: string): integer;
function GetHeight: TGmValue;
function GetLargestFont: TFont;
protected
procedure Draw(ACanvas: TCanvas; Margins: TGmMargins; PageRect: TRect;
APageNum: integer; Scale: Extended); virtual; abstract;
procedure LoadFromStream(AStream: TStream);
procedure SaveToStream(AStream: TStream);
// procedure Print(ACanvas: TCanvas; Margins: TGmMargins; PW, PH, PNum: integer); virtual; abstract;
public
constructor Create(AOwner: TGmPreview);
destructor Destroy; override;
procedure Assign(Source: TPersistent); override;
property Height: TGmValue read GetHeight;
procedure RequestUpdate;
published
property CaptionLeft: string read GetCaptionLeft write SetCaptionLeft;
property CaptionLeftFont: TFont read GetCaptionLeftFont write SetCaptionLeftFont;
property CaptionCenter: string read GetCaptionCenter write SetCaptionCenter;
property CaptionCenterFont: TFont read GetCaptionCenterFont write SetCaptionCenterFont;
property CaptionRight: string read GetCaptionRight write SetCaptionRight;
property CaptionRightFont: TFont read GetCaptionRightFont write SetCaptionRightFont;
property Pen: TPen read FPen write SetPen;
property ShowLine: Boolean read FShowLine write SetShowLine default True;
property Visible: Boolean read FVisible write SetVisible default True;
end;
// *** TGmHeader ***
TGmHeader = class(TGmHeaderFooter)
public
procedure Draw(ACanvas: TCanvas; Margins: TGmMargins; PageRect: TRect;
APageNum: integer; Scale: Extended); override;
end;
// *** TGmFooter ***
TGmFooter = class(TGmHeaderFooter)
public
procedure Draw(ACanvas: TCanvas; Margins: TGmMargins; PageRect: TRect;
APageNum: integer; Scale: Extended); override;
end;
// *** TGmPreview ***
TGmPreviewState = (gmCreating, gmDestroying, gmIdle, gmClearing);
TGmOptions = class(TPersistent)
private
FZoomIn: TGmUserAction;
FZoomOut: TGmUserAction;
procedure SetZoomIn(AUserAction: TGmUserAction);
procedure SetZoomOut(AUserAction: TGmUserAction);
public
constructor Create;
published
property ZoomInAction: TGmUserAction read FZoomIn write SetZoomIn default LeftButton;
property ZoomOutAction: TGmUserAction read FZoomIn write SetZoomOut default RightButton;
end;
TGmPreview = class(TScrollingWinControl)
private
FBorderStyle: TBorderStyle;
FCanvas: TGmCanvas;
FCurrentPage: integer;
FPageHeight: TGmValue;
FPageWidth: TGmValue;
FFooter: TGmFooter;
FGutter: integer;
FHeader: TGmHeader;
FPaperSize: TGmPaperSize;
FMessagesEnabled: Boolean;
FOrientation: TGmOrientation;
FMargins: TGmMargins;
FMaxZoom: integer;
FMinZoom: integer;
FMousePos: TPoint;
FNumPages: integer;
FOptions: TGmOptions;
FPageImage: TGmPageImage;
FPages: TGmPageList;
FPagesPerSheet: TGmPagesPerSheet;
FPanning: Boolean;
FPanningXYStart: TPoint;
FPreviewState: TGmPreviewState;
FPrintBorder: TGmValue;
FPrintCopies: integer;
FPrinter: TGmPrinter;
FPrintFile: string;
FRegisteredComponents: TList;
FZoom: integer;
FZoomIncrement: integer;
FZoomStyle: TGmZoomStyle;
// Events...
FAfterPrint: TNotifyEvent;
FBeforeLoad: TBeforeLoadEvent;
FBeforePrint: TNotifyEvent;
FBeforePrintPage:TBeforePrintPage;
FBeforeReadStream: TBeforeReadStream;
FBeforeWriteStream: TBeforeWriteStream;
FOnAbortPrint: TNotifyEvent;
FOnCanvasChange: TNotifyEvent;
FOnChangeMargins: TNotifyEvent;
FOnChangeOrientation: TNotifyEvent;
FOnChangePageOrientation: TPageOrientationChanged;
FOnChangePrinter: TNotifyEvent;
FOnClear: TNotifyEvent;
FOnDeletePage: TNotifyEvent;
FOnLoadProgress: TFileProgressEvent;
FOnNewPage: TNotifyEvent;
FOnPageChange: TOnPageChangeEvent;
FOnPageMouseDown: TPageMouseEvent;
FOnPageMouseMove: TPageMouseMoveEvent;
FOnPageMouseUp : TPageMouseEvent;
FOnPageSizeChange: TNotifyEvent;
FOnPrintProgress: TOnPrintProgressEvent;
FOnSaveProgress: TFileProgressEvent;
FOnZoom: TOnZoomEvent;
function GetCoordsRelative: TGmCoordsRelative;
function GetFitHeightZoom: integer;
function GetFitWidthZoom: integer;
function GetMetaFile(APage: integer): TMetaFile;
function GetNumPages: integer;
function GetOrientationType: TGmOrientationType;
function GetPage(APage: integer): TGmPage;
function GetPrinterBinIndex: integer;
function GetPrinterBins: TStrings;
function GetPrinterIndex: integer;
function GetPrinters: TStrings;
function GetPrintTitle: string;
function GetShadow: TGmShadow;
function GetVersion: Extended;
function PaperSizeToStr(APaperSize: TGmPaperSize): string;
function StrToPaperSize(APaperStr: string): TGmPaperSize;
procedure CenterPage;
// load/save functions...
procedure LoadPageSetupFromStream(AStream: TStream);
procedure SavePageSetupToStream(AStream: TStream);
procedure LoadDocInfoFromStream(AStream: TStream);
procedure SaveDocInfoToStream(AStream: TStream);
procedure SetBorderStyle(AStyle: TBorderStyle);
procedure SetCoordsRelative(ACoordsRelative: TGmCoordsRelative);
procedure SetCurrentPage(APage: integer);
procedure SetGutter(AGutter: integer);
procedure SetOrientation(AOrientation: TGmOrientation);
procedure SetPagesPerSheet(APagesPerSheet: TGmPagesPerSheet);
procedure SetPaperSize(APaperSize: TGmPaperSize);
procedure SetPrintCopies(APrintCopies: integer);
procedure SetPrinterBinIndex(AIndex: integer);
procedure SetPrinterIndex(AIndex: integer);
procedure SetPrintTitle(ATitle: string);
procedure SetZoom(AZoom: integer);
{ Private declarations }
protected
procedure CMMouseLeave (var Message: TMessage); message CM_MOUSELEAVE;
procedure CreateParams(var Params: TCreateParams); override;
procedure Loaded; override;
procedure MessageToControls(AMessage: integer; Param1, Param2: integer);
procedure MouseMove(Shift: TShiftState; X, Y: Integer); override;
procedure SetParent(AParent: TWinControl); override;
procedure PositionPage;
procedure PreviewResize(var Message: TMessage); message WM_SIZE;
procedure UpdateMessage(var Message: TMessage); message GM_UPDATE_PREVIEW;
procedure MarginsChanged(var Message: TMessage); message GM_USER_MARGINS_CHANGED;
//procedure RegisterComponent(var Message: TMessage); message GM_REGISTER_COMPONENT;
//procedure UnRegisterComponent(var Message: TMessage); message GM_UNREGISTER_COMPONENT;
{ Protected declarations }
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
procedure AddAssociatedComponent(AComponent: TComponent);
procedure RemoveAssociatedComponent(AComponent: TComponent);
function GetFileVersion(AFileName: string): Extended;
function NewPage: TGmPage;
function Tokenize(AText: string; APage: integer): string;
procedure CenterOnClick(x, y: integer);
procedure Clear;
procedure DeleteCurrentPage;
procedure DeletePage(APage: integer);
procedure FirstPage;
procedure FitHeight;
procedure FitWidth;
procedure FitWholePage;
procedure LastPage;
procedure LoadFromStream(AStream: TStream);
procedure LoadFromFile(AFilename: string);
procedure NextPage;
procedure PrevPage;
procedure Print;
procedure PrintRange(AStartPage, AEndPage: integer);
procedure PrintCurrentPage;
procedure PrintToFile(AFileName: string);
procedure SaveToStream(AStream: TStream);
procedure SaveToFile(AFilename: string);
procedure ScrollToPosition(XPercent, YPercent: Extended);
procedure SetCursor(ACursor: TGmCursor);
procedure SetPageSize(AWidth, AHeight: Extended; AUnits: TGmMeasurement);
procedure StartPanning;
procedure StopPanning;
procedure UpdatePreview;
procedure UsePrinterPageSize;
procedure ZoomIn;
procedure ZoomOut;
property Canvas: TGmCanvas read FCanvas write FCanvas;
property CoordsRelativeTo: TGmCoordsRelative read GetCoordsRelative write SetCoordsRelative default fromPage;
property CurrentPage: integer read FCurrentPage write SetCurrentPage;
property MessagesEnabled: Boolean read FMessagesEnabled write FMessagesEnabled;
property MetaFile[APage: Integer]: TMetaFile read GetMetaFile;
property NumPages: integer read GetNumPages;
property Pages[Index: integer]: TGmPage read GetPage;
property PageHeight: TGmValue read FPageHeight write FPageHeight;
property PageWidth: TGmValue read FPageWidth write FPageWidth;
property Panning: Boolean read FPanning;
property PreviewState: TGmPreviewState read FPreviewState;
property PrintBorder: TGmValue read FPrintBorder write FPrintBorder;
property PrinterIndex: integer read GetPrinterIndex write SetPrinterIndex;
property Printers: TStrings read GetPrinters;
property PrinterBins: TStrings read GetPrinterBins;
property PrinterBinIndex: integer read GetPrinterBinIndex write SetPrinterBinIndex;
property Version: Extended read GetVersion;
{ Public declarations }
published
{properties available from Delphi 4...}
{$IFNDEF VER100}
property Anchors;
property Constraints;
{$ENDIF}
// properties...
property Align;
property Color;
property BorderStyle: TBorderStyle read FBorderStyle write SetBorderStyle default bsSingle;
property Footer: TGmFooter read FFooter write FFooter;
property GmPrinter: TGmPrinter read FPrinter write FPrinter;
property Gutter: integer read FGutter write SetGutter;
property Header: TGmHeader read FHeader write FHeader;
property Margins: TGmMargins read FMargins write FMargins;
property MaxZoom: integer read FMaxZoom write FMaxZoom default 400;
property MinZoom: integer read FMinZoom write FMinZoom default 10;
property Orientation: TGmOrientation read FOrientation write SetOrientation;
property PagesPerSheet: TGmPagesPerSheet read FPagesPerSheet write SetPagesPerSheet default gmOnePage;
property PaperSize: TGmPaperSize read FPaperSize write SetPaperSize default A4;
property PrintCopies: integer read FPrintCopies write SetPrintCopies default 1;
property Shadow: TGmShadow read GetShadow;
property ShowHint;
property TabOrder;
property Title: string read GetPrintTitle write SetPrintTitle;
property Visible;
property Zoom: integer read FZoom write SetZoom default DEFAULT_ZOOM;
property ZoomIncrement: integer read FZoomIncrement write FZoomIncrement default 10;
property ZoomStyle: TGmZoomStyle read FZoomStyle write FZoomStyle;
// Events...
property AfterPrint: TNotifyEvent read FAfterPrint write FAfterPrint;
property BeforeLoad: TBeforeLoadEvent read FBeforeLoad write FBeforeLoad;
property BeforePrint: TNotifyEvent read FBeforePrint write FBeforePrint;
property BeforePrintPage: TBeforePrintPage read FBeforePrintPage write FBeforePrintPage;
property BeforeReadStream: TBeforeReadStream read FBeforeReadStream write FBeforeReadStream;
property BeforeWriteStream: TBeforeWriteStream read FBeforeWriteStream write FBeforeWriteStream;
property OnAbortPrint: TNotifyEvent read FOnAbortPrint write FOnAbortPrint;
property OnCanvasChange: TNotifyEvent read FOnCanvasChange write FOnCanvasChange;
property OnChangeMargins: TNotifyEvent read FOnChangeMargins write FOnChangeMargins;
property OnChangeOrientation: TNotifyEvent read FOnChangeOrientation write FOnChangeOrientation;
property OnChangePageOrientation: TPageOrientationChanged read FOnChangePageOrientation write FOnChangePageOrientation;
property OnChangePrinter: TNotifyEvent read FOnChangePrinter write FOnChangePrinter;
property OnClear: TNotifyEvent read FOnClear write FOnClear;
property OnDeletePage: TNotifyEvent read FOnDeletePage write FOnDeletePage;
property OnDragDrop;
property OnDragOver;
property OnEndDrag;
property OnLoadProgess: TFileProgressEvent read FOnLoadProgress write FOnLoadProgress;
property OnMouseDown;
property OnMouseMove;
property OnMouseUp;
property OnNewPage: TNotifyEvent read FOnNewPage write FOnNewPage;
property OnPageChange: TOnPageChangeEvent read FOnPageChange write FOnPageChange;
property OnPageMouseDown: TPageMouseEvent read FOnPageMouseDown write FOnPageMouseDown;
property OnPageMouseMove: TPageMouseMoveEvent read FOnPageMouseMove write FOnPageMouseMove;
property OnPageMouseUp: TPageMouseEvent read FOnPageMouseUp write FOnPageMouseUp;
property OnPageSizeChange: TNotifyEvent read FOnPageSizeChange write FOnPageSizeChange;
property OnPrintProgress: TOnPrintProgressEvent read FOnPrintProgress write FOnPrintProgress;
{$IFNDEF VER100}
property OnResize;
{$ENDIF}
property OnSaveProgress: TFileProgressEvent read FOnSaveProgress write FOnSaveProgress;
property OnStartDrag;
property OnZoom: TOnZoomEvent read FOnZoom write FOnZoom;
{ Published declarations }
end;
// *** Global function declarations ***
function ConvertValue(AValue: Extended; UnitsFrom, UnitsTo: TGmMeasurement): Extended;
function GmPoint(x, y: Extended): TGmPoint;
function GmRect(x, y, x2, y2: Extended): TGmRect;
function MinInt(Int1, Int2: Integer): Integer;
function MaxInt(Int1, Int2: Integer): Integer;
procedure SwapValues(var x,y: integer);
implementation
uses Printers, GmErrors, WinSpool, Consts, GmLegacy;
{$R GmCursors.RES}
//------------------------------------------------------------------------------
// *** Global functions ***
// function similar to "Point" to allow TGmPoint to be cast like... GmPoint(10.4, 6.8)...
function GmPoint(x, y: Extended): TGmPoint;
begin
Result.x := x;
Result.y := y;
end;
// function similar to "Rect" to allow a TGmRect to be defined as GmRect(1,1,5,6);
function GmRect(x, y, x2, y2: Extended): TGmRect;
begin
with Result do
begin
Left := x;
Top := y;
Right := x2;
Bottom := y2;
end;
end;
function MaxInt(Int1, Int2: Integer): Integer;
begin
if Int1 > Int2 then Result := Int1 else Result := Int2;
end;
function MinInt(Int1, Int2: Integer): Integer;
begin
if Int1 < Int2 then Result := Int1 else Result := Int2;
end;
function MaxExt(Ext1, Ext2: Extended): Extended;
begin
if Ext1 > Ext2 then Result := Ext1 else Result := Ext2;
end;
function MinExt(Ext1, Ext2: Extended): Extended;
begin
if Ext1 < Ext2 then Result := Ext1 else Result := Ext2;
end;
function ConvertValue(AValue: Extended; UnitsFrom, UnitsTo: TGmMeasurement): Extended;
var
AsUnits: Extended;
begin
// firstly convert to GmUnits...
AsUnits := AValue;
case UnitsFrom of
GmMillimeters: AsUnits := (AValue * 100);
GmCentimeters: AsUnits := (AValue * 1000);
GmInches : AsUnits := (AValue * 100) * 25.4;
GmPixels : AsUnits :=((AValue * 100) * 25.4) / Screen.PixelsPerInch;
end;
// now convert to the desired measurement...
Result := AsUnits;
case UnitsTo of
GmMillimeters: Result := (AsUnits / 100);
GmCentimeters: Result := (AsUnits / 1000);
GmInches : Result := (AsUnits / 100) / 25.4;
GmPixels : Result :=((AsUnits / 100) / 25.4) * Screen.PixelsPerInch;
end;
end;
function ScreenPpi: Integer;
begin
Result := Screen.PixelsPerInch;
end;
procedure SwapValues(var x,y: integer);
var
z: integer;
begin
z := y;
y := x;
x := z;
end;
procedure GetPaperSize(APaperSize: TGmPaperSize; var AWidth, AHeight: Integer; AOrientation: TGmOrientation);
var
w,h: Integer;
begin
w := AHeight;
h := AWidth;
case APaperSize of
A3:
begin
w := 29700;
h := 42000;
end;
A4:
begin
w := 21000;
h := 29700;
end;
A5:
begin
w := 29700 div 2;
h := 21000;
end;
A6:
begin
w := 21000 div 2;
h := 29700 div 2;
end;
B5:
begin
w := 17600;
h := 25000;
end;
C5:
begin
w := 22900;
h := 16300;
end;
Legal:
begin
w := 21590;
h := 35560;
end;
Letter:
begin
w := 21590;
h := 27940;
end;
end;
if AOrientation = gmPortrait then
begin
AWidth := MinInt(w,h);
AHeight := MaxInt(h,w);
end
else
begin
AWidth := MaxInt(w,h);
AHeight := MinInt(h,w);
end;
end;
function PixelsPerInchX(Handle: THandle): integer;
begin
Result := GetDeviceCaps(Handle, LOGPIXELSX);
end;
function PixelsPerInchY(Handle: THandle): integer;
begin
Result := GetDeviceCaps(Handle, LOGPIXELSY);
end;
function FetchStr(var Str: PChar): PChar;
var
P: PChar;
begin
Result := Str;
if Str = nil then Exit;
P := Str;
while P^ = ' ' do Inc(P);
Result := P;
while (P^ <> #0) and (P^ <> ',') do Inc(P);
if P^ = ',' then
begin
P^ := #0;
Inc(P);
end;
Str := P;
end;
//------------------------------------------------------------------------------
// *** TGmValue ***
constructor TGmValue.Create;
begin
FValue := 0;
end;
function TGmValue.GetAsPixels(Ppi: integer): Integer;
begin
Result := Round((FValue / 2540) * Ppi);
end;
procedure TGmValue.SetAsPixels(Ppi: integer; AValue: Integer);
begin
FValue := Round((AValue * 2540) / Ppi);
if Assigned(FOnChange) then FOnChange(Self);
end;
procedure TGmValue.SetAsMm(AValue: Extended);
begin
FValue := Round(AValue * 100);
if Assigned(FOnChange) then FOnChange(Self);
end;
procedure TGmValue.SetAsCm(AValue: Extended);
begin
FValue := Round((AValue * 100) * 10);
if Assigned(FOnChange) then FOnChange(Self);
end;
procedure TGmValue.SetAsInches(AValue: Extended);
begin
FValue := Round((AValue * 100) * 25.4);
if Assigned(FOnChange) then FOnChange(Self);
end;
function TGmValue.GetAsMm: Extended;
begin
Result := (FValue / 100);
end;
function TGmValue.GetAsCm: Extended;
begin
Result := (FValue / 100) / 10;
end;
function TGmValue.GetAsInches: Extended;
begin
Result := (FValue / 100) / 25.4;
end;
constructor TGmValueRect.Create;
begin
inherited Create;
FLeft := TGmValue.Create;
FTop := TGmValue.Create;
FRight := TGmValue.Create;
FBottom := TGmValue.Create;
end;
destructor TGmValueRect.Destroy;
begin
FLeft.Free;
FTop.Free;
FRight.Free;
FBottom.Free;
inherited Destroy;
end;
//------------------------------------------------------------------------------
// *** TGmPrinter ***
constructor TGmPrinter.Create(AOwner: TGmPreview);
begin
inherited Create;
FPreview := AOwner;
FPrinting := False;
FValue := TGmValue.Create;
FPrinterNames := TStringList.Create;
FPrinterBins := TStringList.Create;
if PrinterSelected then
Printer.PrinterIndex := Printer.PrinterIndex;
Title := '<document>';
FPrinterMargins := TGmValueRect.Create;
UpdatePrinterMargins;
end;
destructor TGmPrinter.Destroy;
begin
FPrinterMargins.Free;
if Assigned(FValue) then FValue.Free;
if Assigned(FPrinterNames) then FPrinterNames.Free;
if Assigned(FPrinterBins) then FPrinterBins.Free;
inherited Destroy;
end;
procedure TGmPrinter.Abort;
begin
if (PrinterSelected) and (FPrinting) then
begin
Printer.Abort;
FPrinting := False;
if Assigned(FPreview.OnAbortPrint) then FPreview.OnAbortPrint(Self);
end;
end;
procedure TGmPrinter.BeginDoc(AFilename: string);
var
CTitle: array[0..31] of Char;
DocInfo: TDocInfo;
begin
if (PrinterSelected) and (not FPrinting) then
begin
if Assigned(FPreview.BeforePrint) then FPreview.BeforePrint(Self);
FPrinting := True;
Printer.BeginDoc;
if AFilename <> '' then
begin
// print to file...
EndPage(Canvas.handle);
Windows.AbortDoc( Canvas.handle );
{ Restart it with a print file as destination. }
StrPLCopy(CTitle, Title, SizeOf(CTitle) - 1);
FillChar(DocInfo, SizeOf(DocInfo), 0);
with DocInfo do
begin
cbSize := SizeOf(DocInfo);
lpszDocName := CTitle;
lpszOutput := PChar(AFilename);
end;
StartDoc(Canvas.handle, DocInfo);
StartPage(Canvas.handle);
end;
end
else
begin
if not PrinterSelected then ShowGmError(FPreview, NO_PRINTER_SELECTED);
if FPrinting then ShowGmError(FPreview, PRINTING_IN_PROGRESS);
end;
end;
procedure TGmPrinter.EndDoc;
begin
if (PrinterSelected) and (FPrinting) then
begin
Printer.EndDoc;
FPrinting := False;
if Assigned(FPreview.AfterPrint) then FPreview.AfterPrint(Self);
end
else
ShowGmError(FPreview, NO_PRINTER_SELECTED);
end;
function TGmPrinter.GetHandle: THandle;
begin
Result := 0;
if PrinterSelected then
Result := Printer.Handle
else
ShowGmError(FPreview, NO_PRINTER_SELECTED);
end;
function TGmPrinter.GetPrinterWidth: TGmValue;
begin
Result := FValue;
Result.AsUnits := 0;
if PrinterSelected then
Result.AsPixels[PrinterPpiX] := GetDeviceCaps(Printer.Handle, PHYSICALWIDTH);
end;
function TGmPrinter.GetPrintQuality: TGmPrintQuality;
var
Device : array[0..MAX_PATH] of char;
Driver : array[0..MAX_PATH] of char;
Port : array[0..MAX_PATH] of char;
hDMode : THandle;
PDMode : PDEVMODE;
begin
Printer.PrinterIndex := Printer.PrinterIndex;
Printer.GetPrinter(Device, Driver, Port, hDMode);
Result := gmDraft;
if hDMode <> 0 then
begin
pDMode := GlobalLock(hDMode);
if pDMode <> nil then
begin
{$IFDEF VER100}
case LongInt(pDMode^.dmPrintQuality) of
{$ELSE}
case LongWord(pDMode^.dmPrintQuality) of
{$ENDIF}
DMRES_DRAFT : Result := gmDraft;
DMRES_LOW : Result := gmLow;
DMRES_MEDIUM: Result := gmMedium;
DMRES_HIGH : Result := gmHigh;
end;
GlobalUnlock(hDMode);
Printer.PrinterIndex := Printer.PrinterIndex;
end;
end;
end;
function TGmPrinter.GetPrinterHeight: TGmValue;
begin
Result := FValue;
Result.AsUnits := 0;
if PrinterSelected then
Result.AsPixels[PrinterPpiX] := GetDeviceCaps(Printer.Handle, PHYSICALHEIGHT);
end;
function TGmPrinter.GetPrinterAvailableWidth: TGmValue;
begin
Result := FValue;
Result.AsUnits := 0;
if PrinterSelected then
Result.AsPixels[PrinterPpiX] := GetDeviceCaps(Printer.Handle, HORZRES);
end;
function TGmPrinter.GetPrinterAvailableHeight: TGmValue;
begin
Result := FValue;
Result.AsUnits := 0;
if PrinterSelected then
Result.AsPixels[PrinterPpiX] := GetDeviceCaps(Printer.Handle, VERTRES);
end;
{function TGmPrinter.InchesToPrinterPixels(AUnits: Extended): integer;
begin
Result := 0;
if PrinterSelected then
Result := Round(PixelsPerInchX(Printer.Handle) * AUnits);
end;}
function TGmPrinter.PrinterPpiX: integer;
begin
Result := 0;
if PrinterSelected then
Result := PixelsPerInchX(GetHandle);
end;
function TGmPrinter.PrinterPpiY: integer;
begin
Result := 0;
if PrinterSelected then
Result := PixelsPerInchY(GetHandle);
end;
procedure TGmPrinter.NewPage(Orientation: TGmOrientation);
var
Device : array[0..MAX_PATH] of char;
Driver : array[0..MAX_PATH] of char;
Port : array[0..MAX_PATH] of char;
hDeviceMode: THandle;
pDevMode: PDeviceMode;
begin
if (PrinterSelected) and (FPrinting) then
begin
Printer.GetPrinter(Device, Driver, Port, hDeviceMode);
pDevMode := GlobalLock( hDevicemode );
with pDevMode^ do
begin
dmFields := dmFields or DM_ORIENTATION;
case Orientation of
gmPortrait : dmOrientation := DMORIENT_PORTRAIT;
gmLandscape : dmOrientation := DMORIENT_LANDSCAPE;
end;
end;
Windows.EndPage( Printer.Handle );
ResetDC( canvas.Handle, pDevMode^ );
GlobalUnlock( hDeviceMode );
Windows.StartPage( Printer.Handle );
Printer.Canvas.Refresh;
end;
end;
procedure TGmPrinter.ResetPrinter;
var
Device, Driver, Port: array[0..80] of Char;
DevMode: THandle;
begin
if PrinterSelected then
begin
Printer.GetPrinter(Device, Driver, Port, DevMode);
Printer.SetPrinter(Device, Driver, Port, 0);
UpdatePrinterMargins;
end;
end;
function TGmPrinter.GetCanvas: TCanvas;
begin
if FPrinting then Result := Printer.Canvas else Result := nil;
end;
function TGmPrinter.GetDitherType: TGmDitherType;
var
Device : array[0..MAX_PATH] of char;
Driver : array[0..MAX_PATH] of char;
Port : array[0..MAX_PATH] of char;
hDMode : THandle;
PDMode : PDEVMODE;
begin
Printer.PrinterIndex := Printer.PrinterIndex;
Printer.GetPrinter(Device, Driver, Port, hDMode);
Result := gmNone;
if hDMode <> 0 then
begin
pDMode := GlobalLock(hDMode);
if pDMode <> nil then
begin
//if (pDMode^.dmFields and dm_Color) = dm_Color then
//begin
case pDMode^.dmDitherType of
DMDITHER_NONE : Result := gmNone;
DMDITHER_COARSE : Result := gmCourse;
DMDITHER_FINE : Result := gmFine;
DMDITHER_LINEART : Result := gmLineArt;
DMDITHER_GRAYSCALE : Result := gmGrayScale;
end;
GlobalUnlock(hDMode);
Printer.PrinterIndex := Printer.PrinterIndex;
end;
end;
end;
function TGmPrinter.GetDuplexType: TGmDuplexType;
var
Device : array[0..MAX_PATH] of char;
Driver : array[0..MAX_PATH] of char;
Port : array[0..MAX_PATH] of char;
hDMode : THandle;
PDMode : PDEVMODE;
begin
Printer.PrinterIndex := Printer.PrinterIndex;
Printer.GetPrinter(Device, Driver, Port, hDMode);
Result := gmSimplex;
if hDMode <> 0 then
begin
pDMode := GlobalLock(hDMode);
if pDMode <> nil then
begin
case pDMode^.dmDuplex of
DMDUP_SIMPLEX : Result := gmSimplex;
DMDUP_HORIZONTAL : Result := gmHorzDuplex;
DMDUP_VERTICAL : Result := gmVertDuplex;
end;
GlobalUnlock(hDMode);
Printer.PrinterIndex := Printer.PrinterIndex;
end;
end;
end;
function TGmPrinter.GetIndexOf(APrinter: string): integer;
begin
Result := FPrinterNames.IndexOf(APrinter);
end;
function TGmPrinter.GetIsColorPrinter : Boolean;
var
Device : array[0..MAX_PATH] of char;
Driver : array[0..MAX_PATH] of char;
Port : array[0..MAX_PATH] of char;
hDMode : THandle;
PDMode : PDEVMODE;
begin
Result := False;
Printer.PrinterIndex := Printer.PrinterIndex;
Printer.GetPrinter(Device, Driver, Port, hDMode);
if hDMode <> 0 then
begin
pDMode := GlobalLock(hDMode);
if pDMode <> nil then
begin
if ((pDMode^.dmFields and dm_Color) = dm_Color) then
begin
Result := True;
end;
GlobalUnlock(hDMode);
end;
end;
end;
function TGmPrinter.GetPrintColorMode: TGmPrintColor;
var
Device : array[0..MAX_PATH] of char;
Driver : array[0..MAX_PATH] of char;
Port : array[0..MAX_PATH] of char;
hDMode : THandle;
PDMode : PDEVMODE;
begin
Printer.PrinterIndex := Printer.PrinterIndex;
Printer.GetPrinter(Device, Driver, Port, hDMode);
Result := gmMonochrome;
if hDMode <> 0 then
begin
pDMode := GlobalLock(hDMode);
if pDMode <> nil then
begin
//if (pDMode^.dmFields and dm_Color) = dm_Color then
//begin
case pDMode^.dmColor of
DMCOLOR_COLOR : Result := gmColor;
DMCOLOR_MONOCHROME: Result := gmMonochrome;
end;
GlobalUnlock(hDMode);
Printer.PrinterIndex := Printer.PrinterIndex;
end;
end;
end;
function TGmPrinter.GetPrinterIndex: integer;
begin
Result := -1;
if PrinterSelected then
Result := Printer.PrinterIndex;
end;
function TGmPrinter.GetPrinters: TStrings;
var
LineCur, Port: PChar;
Buffer, PrinterInfo: PChar;
Flags, Count, NumInfo: DWORD;
I: Integer;
Level: Byte;
ServerText: string;
begin
if FPrinterNames = nil then
FPrinterNames := TStringList.Create;
FPrinterNames.Clear;
Result := FPrinterNames;
try
if Win32Platform = VER_PLATFORM_WIN32_NT then
begin
Flags := PRINTER_ENUM_CONNECTIONS or PRINTER_ENUM_LOCAL;
Level := 4;
end
else
begin
Flags := PRINTER_ENUM_LOCAL;
Level := 5;
end;
Count := 0;
EnumPrinters(Flags, nil, Level, nil, 0, Count, NumInfo);
if Count = 0 then Exit;
GetMem(Buffer, Count);
try
if not EnumPrinters(Flags, nil, Level, PByte(Buffer), Count, Count, NumInfo) then
Exit;
PrinterInfo := Buffer;
for I := 0 to NumInfo - 1 do
begin
if Level = 4 then
with PPrinterInfo4(PrinterInfo)^ do
begin
if FShowServer = True then ServerText := pServerName else ServerText := '';
FPrinterNames.AddObject(ServerText + pPrinterName,
TPrinterDevice.Create(nil, pPrinterName, nil));
Inc(PrinterInfo, sizeof(TPrinterInfo4));
end
else
with PPrinterInfo5(PrinterInfo)^ do
begin
LineCur := pPortName;
Port := FetchStr(LineCur);
while Port^ <> #0 do
begin
//if FShowServer = True then ServerText := pPortName else ServerText := '';
FPrinterNames.AddObject(Format(SDeviceOnPort, [pPrinterName, Port]),
TPrinterDevice.Create(nil, pPrinterName, Port));
Port := FetchStr(LineCur);
end;
Inc(PrinterInfo, sizeof(TPrinterInfo5));
end;
end;
finally
FreeMem(Buffer, Count);
end;
except
FPrinterNames.Free;
FPrinterNames := nil;
raise;
end;
Result := FPrinterNames;
end;
function TGmPrinter.GetOffset: TPoint;
begin
// get the offset as printer pixels...
Result.x := 0;
Result.y := 0;
if PrinterSelected then
begin
Result.x := GetDeviceCaps(Printer.Handle, PHYSICALOFFSETX);
Result.y := GetDeviceCaps(Printer.Handle, PHYSICALOFFSETY);
end;
end;
function TGmPrinter.GetOrientation: TGmOrientation;
begin
Result := gmPortrait;
if PrinterSelected then
case Printer.Orientation of
poPortrait : Result := gmPortrait;
poLandscape : Result := gmLandscape;
end;
end;
function TGmPrinter.GetPrinterBins: TStrings;
var
Device, Driver, Port: array[0..80] of Char;
p : array[0..255] of Char;
ICount: Integer;
{$IFDEF VER100}
FHandle: Integer;
{$ELSE}
FHandle: Cardinal;
{$ENDIF}
begin
if not Assigned(FPrinterBins) then
FPrinterBins := TStringList.Create;
FPrinterBins.Clear;
if PrinterSelected then
begin
Printer.GetPrinter(Device, Driver, Port, FHandle);
with FPrinterBins do begin
for ICount:=1 to DeviceCapabilities(Device,Port,DC_BINNAMES,p,nil) do
Add(p+24*(ICount-1));
end;
end;
Result := FPrinterBins;
end;
function TGmPrinter.GetPrinterBinIndex: integer;
var
DevMode: PDevMode;
FDevice: array[0..255] of Char;
FDriver: array[0..255] of Char;
FPort: array[0..255] of Char;
{$IFDEF VER100}
FHandle: Integer;
{$ELSE}
FHandle: Cardinal;
{$ENDIF}
begin
Result := -1;
if PrinterSelected then
begin
Printer.GetPrinter(FDevice, FDriver, FPort, FHandle);
DevMode := GlobalLock(FHandle);
with DevMode^ do
Result := dmDefaultSource;
GlobalUnlock(FHandle);
end;
end;
function TGmPrinter.GetPrinterInstalled: Boolean;
begin
Result := Printer.Printers.Count > 0;
end;
function TGmPrinter.GetPrinterMargin(index: integer): TGmValue;
var
Offset: TPoint;
PpiX, PpiY: integer;
begin
Result := FValue;
// returns the 4 printer margins as inches...
Result.AsUnits := 0;
if PrinterSelected then
begin
PpiX := PixelsPerInchX(Printer.Handle);
PpiY := PixelsPerInchY(Printer.Handle);
Offset := GetOffset;
case Index of
0: Result.AsPixels[PpiX] := Round(Offset.x);
1: Result.AsPixels[PpiY] := Round(Offset.y);
2: Result.AsPixels[PpiX] := Round(Offset.x);
3: Result.AsPixels[PpiY] := Round(Offset.y);
// 1: Result.AsInches := Offset.y / PpiY;
// 2: Result.AsInches := ((PrinterWidth.AsInches - AvailableWidth.AsInches)+Offset.X))/PpiX;
// 3: Result.AsInches := ((PrinterHeight.AsInches - AvailableHeight.AsInches)+Offset.Y))/PpiY;
end;
end;
end;
function TGmPrinter.GetPrinterSelected: Boolean;
begin
Result := False;
if GetPrinterInstalled then
Result := True;
end;
function TGmPrinter.GetTitle: string;
begin
Result := '';
if PrinterSelected then
Result := Printer.Title;
end;
procedure TGmPrinter.SetDitherType(ADitherType: TGmDitherType);
var
Device : array[0..MAX_PATH] of char;
Driver : array[0..MAX_PATH] of char;
Port : array[0..MAX_PATH] of char;
hDMode : THandle;
PDMode : PDEVMODE;
begin
Printer.PrinterIndex := Printer.PrinterIndex;
Printer.GetPrinter(Device, Driver, Port, hDMode);
if hDMode <> 0 then
begin
pDMode := GlobalLock(hDMode);
if pDMode <> nil then
begin
case ADitherType of
gmNone : pDMode^.dmDitherType := DMDITHER_NONE;
gmCourse : pDMode^.dmDitherType := DMDITHER_COARSE;
gmFine : pDMode^.dmDitherType := DMDITHER_FINE;
gmLineArt : pDMode^.dmDitherType := DMDITHER_LINEART;
gmGrayScale : pDMode^.dmDitherType := DMDITHER_GRAYSCALE;
end;
GlobalUnlock(hDMode);
Printer.PrinterIndex := Printer.PrinterIndex;
end;
end;
end;
procedure TGmPrinter.SetDuplexType(ADuplexType: TGmDuplexType);
var
Device : array[0..MAX_PATH] of char;
Driver : array[0..MAX_PATH] of char;
Port : array[0..MAX_PATH] of char;
hDMode : THandle;
PDMode : PDEVMODE;
begin
Printer.PrinterIndex := Printer.PrinterIndex;
Printer.GetPrinter(Device, Driver, Port, hDMode);
if hDMode <> 0 then
begin
pDMode := GlobalLock(hDMode);
if pDMode <> nil then
begin
case ADuplexType of
gmSimplex : pDMode^.dmDuplex := DMDUP_SIMPLEX;
gmHorzDuplex : pDMode^.dmDitherType := DMDUP_HORIZONTAL;
gmVertDuplex : pDMode^.dmDitherType := DMDUP_VERTICAL;
end;
GlobalUnlock(hDMode);
Printer.PrinterIndex := Printer.PrinterIndex;
end;
end;
end;
procedure TGmPrinter.SetOrientation(AOrientation: TGmOrientation);
function GmOrientationToPrinterOrientation(AValue: TGmOrientation): TPrinterOrientation;
begin
Result := poPortrait;
if AValue = gmLandScape then Result := poPortrait;
end;
begin
if PrinterSelected then
begin
if Printer.Orientation <> GmOrientationToPrinterOrientation(AOrientation) then
Printer.Orientation := GmOrientationToPrinterOrientation(AOrientation);
end;
end;
procedure TGmPrinter.SetPrinterColorMode(AColor : TGmPrintColor);
var
Device : array[0..MAX_PATH] of char;
Driver : array[0..MAX_PATH] of char;
Port : array[0..MAX_PATH] of char;
hDMode : THandle;
PDMode : PDEVMODE;
begin
Printer.PrinterIndex := Printer.PrinterIndex;
Printer.GetPrinter(Device, Driver, Port, hDMode);
if hDMode <> 0 then
begin
pDMode := GlobalLock(hDMode);
if pDMode <> nil then
begin
if (pDMode^.dmFields and dm_Color) = dm_Color then
begin
case AColor of
gmColor : pDMode^.dmColor := DMCOLOR_COLOR;
gmMonochrome: pDMode^.dmColor := DMCOLOR_MONOCHROME;
end;
end;
GlobalUnlock(hDMode);
Printer.PrinterIndex := Printer.PrinterIndex;
end;
end;
end;
procedure TGmPrinter.SetPrinterIndex(index: integer);
begin
if PrinterSelected then
begin
if index <> PrinterIndex then
begin
Printer.PrinterIndex := Index;
ResetPrinter;
if Assigned(FPreview.OnChangePrinter) then FPreview.OnChangePrinter(Self);
end;
end
else
ShowGmError(FPreview, NO_PRINTER_SELECTED);
end;
procedure TGmPrinter.SetPrinterBinIndex(index: integer);
var
DevMode: PDevMode;
FDevice: array[0..255] of Char;
FDriver: array[0..255] of Char;
FPort: array[0..255] of Char;
{$IFDEF VER100}
FHandle: Integer;
{$ELSE}
FHandle: Cardinal;
{$ENDIF}
begin
if PrinterSelected then
begin
Printer.GetPrinter(FDevice, FDriver, FPort, FHandle);
DevMode := GlobalLock(FHandle);
with DevMode^ do
begin
dmFields := DM_DEFAULTSOURCE;
dmDefaultSource := Index;
end;
GlobalUnlock(FHandle);
end
else
ShowGmError(FPreview, NO_PRINTER_SELECTED);
end;
procedure TGmPrinter.SetPrintQuality(AQuality: TGmPrintQuality);
var
Device : array[0..MAX_PATH] of char;
Driver : array[0..MAX_PATH] of char;
Port : array[0..MAX_PATH] of char;
hDMode : THandle;
PDMode : PDEVMODE;
begin
Printer.PrinterIndex := Printer.PrinterIndex;
Printer.GetPrinter(Device, Driver, Port, hDMode);
if hDMode <> 0 then
begin
pDMode := GlobalLock(hDMode);
if pDMode <> nil then
begin
if (pDMode^.dmFields and dm_printquality) = dm_printquality then
begin
case AQuality of
gmDraft : pDMode^.dmPrintQuality := Short(DMRES_DRAFT);
gmLow : pDMode^.dmPrintQuality := Short(DMRES_LOW);
gmMedium: pDMode^.dmPrintQuality := Short(DMRES_MEDIUM);
gmHigh : pDMode^.dmPrintQuality := Short(DMRES_HIGH);
end;
end;
GlobalUnlock(hDMode);
Printer.PrinterIndex := Printer.PrinterIndex;
end;
end;
end;
procedure TGmPrinter.SetShowServer(AValue: Boolean);
begin
FShowServer := AValue;
end;
procedure TGmPrinter.SetTitle(ATitle: string);
begin
if (PrinterSelected) and (not FPrinting) then
Printer.Title := ATitle;
end;
procedure TGmPrinter.UpdatePrinterMargins;
begin
FPrinterMargins.Left.AsUnits := GetPrinterMargin(0).AsUnits;
FPrinterMargins.Top.AsUnits := GetPrinterMargin(1).AsUnits;
FPrinterMargins.Right.AsUnits := GetPrinterMargin(2).AsUnits;
FPrinterMargins.Bottom.AsUnits := GetPrinterMargin(3).AsUnits;
//FillGmUnits(FPrinterMargins.Left);
//FillGmUnits(FPrinterMargins.Right);
//FillGmUnits(FPrinterMargins.Top);
//FillGmUnits(FPrinterMargins.Bottom);
end;
constructor TPrinterDevice.Create(ADriver, ADevice, APort: PChar);
begin
inherited Create;
Driver := ADriver;
Device := ADevice;
Port := APort;
end;
//------------------------------------------------------------------------------
// *** TGmCanvas ***
constructor TGmCanvas.Create(AOwner: TGmPreview);
begin
inherited Create;
FPreview := AOwner;
FBrush := TBrush.Create;
FCopyMode := cmSrcCopy;
FDefaultMeasurement := GmMillimeters;
FFont := TFont.Create;
FPen := TPen.Create;
FTempMetafile := TMetafile.Create;
FTempCanvas := TMetafileCanvas.Create(FTempMetafile, 0);
FCoordsRelative := fromPage;
FFont.Name := DEFAULT_FONT;
FValue1 := TGmValue.Create;
FValue2 := TGmValue.Create;
FSavedPen := TPen.Create;
FSavedBrush := TBrush.Create;
end;
destructor TGmCanvas.Destroy;
begin
FBrush.Free;
FTempCanvas.Free;
FTempMetafile.Free;
FFont.Free;
FPen.Free;
FValue1.Free;
FValue2.Free;
FSavedPen.Free;
FSavedBrush.Free;
inherited Destroy;
end;
function TGmCanvas.GraphicHeight(AGraphic: TGraphic): TGmValue;
begin
Result := FValue1;
FValue1.AsPixels[ScreenPpi] := AGraphic.Height;
end;
function TGmCanvas.GraphicWidth(AGraphic: TGraphic): TGmValue;
begin
Result := FValue1;
FValue1.AsPixels[ScreenPpi] := AGraphic.Width;
end;
function TGmCanvas.TextHeight(AText: string): TGmValue;
begin
// work out height and pass back a TGmValue record type...
Result := FValue1;
FTempCanvas.Font.Assign(FFont);
Result.AsPixels[ScreenPpi] := FTempCanvas.TextHeight(AText);
end;
function TGmCanvas.TextWidth(AText: string): TGmValue;
begin
// work out height and pass back a TGmValue record type...
Result := FValue1;
FTempCanvas.Font.Assign(FFont);
Result.AsPixels[ScreenPpi] := FTempCanvas.TextWidth(AText);
end;
{procedure TGmCanvas.BrushChange(Sender: TObject);
begin
FCanvas.Brush.Assign(FBrush);
end;
procedure TGmCanvas.FontChange(Sender: TObject);
begin
FCanvas.Font.Assign(FFont);
end;
procedure TGmCanvas.PenChange(Sender: TObject);
begin
FCanvas.Pen.Assign(FPen);
end; }
procedure TGmCanvas.Arc(x, y, x2, y2, x3, y3, x4, y4: Extended; GmMeasurement: TGmMeasurement);
var
AArcShape: TGmArcShape;
begin
// Create an Ellipse object and add it to the page objects list...
AArcShape := TGmArcShape.Create;
AArcShape.Brush := BrushToGmBrush(FBrush);
AArcShape.Pen := PenToGmPen(FPen);
AArcShape.X := Round(ConvertValue(x, GmMeasurement, GmUnits))+ GetLeft;
AArcShape.Y := Round(ConvertValue(y, GmMeasurement, GmUnits)) + GetTop;
AArcShape.X2 := Round(ConvertValue(x2, GmMeasurement, GmUnits))+ GetLeft;
AArcShape.Y2 := Round(ConvertValue(y2, GmMeasurement, GmUnits)) + GetTop;
AArcShape.X3 := Round(ConvertValue(x3, GmMeasurement, GmUnits))+ GetLeft;
AArcShape.Y3 := Round(ConvertValue(y3, GmMeasurement, GmUnits)) + GetTop;
AArcShape.X4 := Round(ConvertValue(x4, GmMeasurement, GmUnits))+ GetLeft;
AArcShape.Y4 := Round(ConvertValue(y4, GmMeasurement, GmUnits)) + GetTop;
FPage.AddObject(AArcShape);
end;
procedure TGmCanvas.Chord(x, y, x2, y2, x3, y3, x4, y4: Extended; GmMeasurement: TGmMeasurement);
var
AChordShape: TGmChordShape;
begin
// Create an Ellipse object and add it to the page objects list...
AChordShape := TGmChordShape.Create;
AChordShape.Brush := BrushToGmBrush(FBrush);
AChordShape.Pen := PenToGmPen(FPen);
AChordShape.X := Round(ConvertValue(x, GmMeasurement, GmUnits))+ GetLeft;;
AChordShape.Y := Round(ConvertValue(y, GmMeasurement, GmUnits)) + GetTop;
AChordShape.X2 := Round(ConvertValue(x2, GmMeasurement, GmUnits))+ GetLeft;;
AChordShape.Y2 := Round(ConvertValue(y2, GmMeasurement, GmUnits)) + GetTop;
AChordShape.X3 := Round(ConvertValue(x3, GmMeasurement, GmUnits))+ GetLeft;;
AChordShape.Y3 := Round(ConvertValue(y3, GmMeasurement, GmUnits)) + GetTop;
AChordShape.X4 := Round(ConvertValue(x4, GmMeasurement, GmUnits))+ GetLeft;;
AChordShape.Y4 := Round(ConvertValue(y4, GmMeasurement, GmUnits)) + GetTop;
FPage.AddObject(AChordShape);
end;
procedure TGmCanvas.Draw(x, y: Extended; AGraphic: TGraphic; Scale: Extended; GmMeasurement: TGmMeasurement);
var
ARect: TRect;
begin
ARect.Left := Round(ConvertValue(x, GmMeasurement, GmUnits))+ GetLeft;;
ARect.Top := Round(ConvertValue(y, GmMeasurement, GmUnits)) + GetTop;
ARect.Right := Round(ConvertValue(x, GmMeasurement, GmUnits))+ Round(GraphicWidth(AGraphic).AsUnits*Scale)+ GetLeft;;
ARect.Bottom := Round(ConvertValue(y, GmMeasurement, GmUnits))+ Round(GraphicHeight(AGraphic).AsUnits*Scale) + GetTop;
StretchDraw(ARect.Left, ARect.Top, ARect.Right, ARect.Bottom, AGraphic, GmUnits);
CanvasChanged;
end;
function TGmCanvas.GetLeft: integer;
var
APreview: TGmPreview;
begin
APreview := FPage.FPreview;
case FCoordsRelative of
fromPrinterMargins: Result := APreview.GmPrinter.PrinterMargins.Left.AsUnits;
fromUserMargins: Result := APreview.Margins.Left.AsUnits;
fromHeaderLine: Result := APreview.Margins.Left.AsUnits;
else
Result := 0;
end;
end;
procedure TGmCanvas.CanvasChanged;
begin
if Assigned(FPreview.OnCanvasChange) then FPreview.OnCanvasChange(Self);
end;
function TGmCanvas.GetTop: integer;
var
APreview: TGmPreview;
begin
APreview := FPage.FPreview;
case FCoordsRelative of
fromPrinterMargins: Result := APreview.GmPrinter.PrinterMargins.Top.AsUnits;
fromUserMargins: Result := APreview.Margins.Top.AsUnits;
fromHeaderLine: Result := APreview.Margins.Top.AsUnits + APreview.Header.Height.AsUnits;
else
Result := 0;
end;
end;
procedure TGmCanvas.DrawRect(x, y, x2, y2: Extended; GmMeasurement: TGmMeasurement; RectType: TGmRectType);
var
ARectangleShape: TGmRectangleShape;
begin
// Create a rectangle object and add it to the page objects list...
ARectangleShape := TGmRectangleShape.Create;
ARectangleShape.Brush := BrushToGmBrush(FBrush);
ARectangleShape.Pen := PenToGmPen(FPen);
ARectangleShape.X := Round(ConvertValue(x, GmMeasurement, GmUnits)) + GetLeft;
ARectangleShape.Y := Round(ConvertValue(y, GmMeasurement, GmUnits)) + GetTop;
ARectangleShape.X2 := Round(ConvertValue(x2, GmMeasurement, GmUnits))+ GetLeft;
ARectangleShape.Y2 := Round(ConvertValue(y2, GmMeasurement, GmUnits))+ GetTop;
ARectangleShape.RectType:= RectType;
FPage.AddObject(ARectangleShape);
end;
procedure TGmCanvas.Ellipse(x, y, x2, y2: Extended; GmMeasurement: TGmMeasurement);
var
AEllipseShape: TGmEllipseShape;
begin
// Create an Ellipse object and add it to the page objects list...
AEllipseShape := TGmEllipseShape.Create;
AEllipseShape.Brush := BrushToGmBrush(FBrush);
AEllipseShape.Pen := PenToGmPen(FPen);
AEllipseShape.X := Round(ConvertValue(x, GmMeasurement, GmUnits))+ GetLeft;;
AEllipseShape.Y := Round(ConvertValue(y, GmMeasurement, GmUnits)) + GetTop;
AEllipseShape.X2 := Round(ConvertValue(x2, GmMeasurement, GmUnits))+ GetLeft;;
AEllipseShape.Y2 := Round(ConvertValue(y2, GmMeasurement, GmUnits)) + GetTop;
FPage.AddObject(AEllipseShape);
end;
procedure TGmCanvas.FillRect(x, y, x2, y2: Extended; GmMeasurement: TGmMeasurement);
begin
DrawRect(x, y, x2, y2, GmMeasurement, gmFillRect);
end;
procedure TGmCanvas.FloatOut(x, y, AValue: Extended; Format: string; GmMeasurement: TGmMeasurement);
var
ATextObject: TGmTextObject;
//Unused : Extended;
begin
// create a text object and set its values...
ATextObject := TGmTextObject.Create;
ATextObject.Caption := FormatFloat(Format, AValue);
x := (ConvertValue(x, GmMeasurement, GmUnits)- TextWidth(ATextObject.Caption).AsUnits) + GetLeft;;
y := ConvertValue(y, GmMeasurement, GmUnits) + GetTop;
ATextObject.X := Round(x);
ATextObject.Y := Round(y);
ATextObject.Brush := BrushToGmBrush(FBrush);
ATextObject.Font := FontToGmFont(FFont);
FPage.AddObject(ATextObject);
end;
procedure TGmCanvas.Line(x, y, x2, y2: Extended; GmMeasurement: TGmMeasurement);
var
ALineObject: TGmLineObject;
begin
ALineObject := TGmLineObject.Create;
ALineObject.Pen := PenToGmPen(FPen);
ALineObject.X := Round(ConvertValue(x, GmMeasurement, GmUnits))+ GetLeft;;
ALineObject.Y := Round(ConvertValue(y, GmMeasurement, GmUnits)) + GetTop;
ALineObject.X2 := Round(ConvertValue(x2, GmMeasurement, GmUnits))+ GetLeft;;
ALineObject.Y2 := Round(ConvertValue(y2, GmMeasurement, GmUnits)) + GetTop;
FPage.AddObject(ALineObject);
end;
procedure TGmCanvas.LineExt(x, y, x2, y2: Extended; LineWidth: Integer; GmMeasurement: TGmMeasurement);
begin
{ TODO : line thickness }
Line(x, y, x2, y2, GmMeasurement);
end;
procedure TGmCanvas.LineTo(x, y: Extended; GmMeasurement: TGmMeasurement);
begin
x := ConvertValue(x, GmMeasurement, GmUnits);
y := ConvertValue(y, GmMeasurement, GmUnits);
Line(FCurrentPos.X, FCurrentPos.Y, x, y, GmUnits);
FCurrentPos.X := Round(x);
FCurrentPos.Y := Round(y);
end;
procedure TGmCanvas.MoveTo(x, y: Extended; GmMeasurement: TGmMeasurement);
begin
FCurrentPos.X := Round(ConvertValue(x, GmMeasurement, GmUnits)) + GetLeft;;
FCurrentPos.Y := Round(ConvertValue(y, GmMeasurement, GmUnits)) + GetTop;
end;
procedure TGmCanvas.Pie(x, y, x2, y2, x3, y3, x4, y4: Extended; GmMeasurement: TGmMeasurement);
var
APieShape: TGmPieShape;
begin
// Create an Ellipse object and add it to the page objects list...
APieShape := TGmPieShape.Create;
APieShape.Brush := BrushToGmBrush(FBrush);
APieShape.Pen := PenToGmPen(FPen);
APieShape.X := Round(ConvertValue(x, GmMeasurement, GmUnits)) + GetLeft;
APieShape.Y := Round(ConvertValue(y, GmMeasurement, GmUnits)) + GetTop;
APieShape.X2 := Round(ConvertValue(x2, GmMeasurement, GmUnits)) + GetLeft;
APieShape.Y2 := Round(ConvertValue(y2, GmMeasurement, GmUnits)) + GetTop;
APieShape.X3 := Round(ConvertValue(x3, GmMeasurement, GmUnits)) + GetLeft;
APieShape.Y3 := Round(ConvertValue(y3, GmMeasurement, GmUnits)) + GetTop;
APieShape.X4 := Round(ConvertValue(x4, GmMeasurement, GmUnits)) + GetLeft;
APieShape.Y4 := Round(ConvertValue(y4, GmMeasurement, GmUnits)) + GetTop;
FPage.AddObject(APieShape);
end;
{$IFNDEF VER100}
procedure TGmCanvas.Polygon(Points: array of TGmPoint; GmMeasurement: TGmMeasurement);
var
APolygonObject: TGmPolyBaseObject;
count: integer;
x, y: Extended;
begin
// create a new polygon object and set its values...
APolygonObject := TGmPolygonObject.Create;
SetLength(APolygonObject.Points, High(Points)+1);
for count := 0 to High(Points) do
begin
x := ConvertValue(Points[count].x, GmMeasurement, GmUnits) + GetLeft;
y := ConvertValue(Points[count].y, GmMeasurement, GmUnits) + GetTop;
APolygonObject.Points[count].x := Round(x);
APolygonObject.Points[count].y := Round(y);
end;
APolygonObject.Brush := BrushToGmBrush(FBrush);
APolygonObject.Pen := PenToGmPen(FPen);
FPage.AddObject(APolygonObject);
end;
procedure TGmCanvas.PolyLine(Points: array of TGmPoint; GmMeasurement: TGmMeasurement);
var
APolylineObject: TGmPolyBaseObject;
count: integer;
x, y: Extended;
begin
// create a new polygon object and set its values...
APolylineObject := TGmPolyLineObject.Create;
SetLength(APolylineObject.Points, High(Points)+1);
for count := 0 to High(Points) do
begin
x := ConvertValue(Points[count].x, GmMeasurement, GmUnits) + GetLeft;
y := ConvertValue(Points[count].y, GmMeasurement, GmUnits) + GetTop;
APolylineObject.Points[count].x := Round(x);
APolylineObject.Points[count].y := Round(y);
end;
APolylineObject.Brush := BrushToGmBrush(FBrush);
APolylineObject.Pen := PenToGmPen(FPen);
FPage.AddObject(APolylineObject);
end;
procedure TGmCanvas.PolyLineTo(Points: array of TGmPoint; GmMeasurement: TGmMeasurement);
begin
PolyLine(Points, GmMeasurement);
FCurrentPos.x := Round(ConvertValue(Points[High(Points)].x, GmMeasurement, GmUnits)) + GetLeft;
FCurrentPos.y := Round(ConvertValue(Points[High(Points)].y, GmMeasurement, GmUnits)) + GetTop;
end;
procedure TGmCanvas.PolyBezier(Points: array of TGmPoint; GmMeasurement: TGmMeasurement);
var
APolyBezierObject: TGmPolyBezierObject;
count: integer;
x, y: Extended;
begin
// create a new polygon object and set its values...
APolyBezierObject := TGmPolyBezierObject.Create;
SetLength(APolyBezierObject.Points, High(Points)+1);
for count := 0 to High(Points) do
begin
x := ConvertValue(Points[count].x, GmMeasurement, GmUnits) + GetLeft;
y := ConvertValue(Points[count].y, GmMeasurement, GmUnits) + GetTop;
APolyBezierObject.Points[count].x := Round(x);
APolyBezierObject.Points[count].y := Round(y);
end;
APolyBezierObject.Brush := BrushToGmBrush(FBrush);
APolyBezierObject.Pen := PenToGmPen(FPen);
FPage.AddObject(APolyBezierObject);
end;
procedure TGmCanvas.PolyBezierTo(Points: array of TGmPoint; GmMeasurement: TGmMeasurement);
begin
PolyBezier(Points, GmMeasurement);
FCurrentPos.x := Round(ConvertValue(Points[High(Points)].x, GmMeasurement, GmUnits)) + GetLeft;
FCurrentPos.y := Round(ConvertValue(Points[High(Points)].y, GmMeasurement, GmUnits)) + GetTop;
end;
{$ENDIF}
procedure TGmCanvas.Rectangle(x, y, x2, y2: Extended; GmMeasurement: TGmMeasurement);
begin
DrawRect(x, y, x2, y2, GmMeasurement, gmRectangle);
end;
procedure TGmCanvas.RotateOut(x, y, Angle: Extended; AText: string; GmMeasurement: TGmMeasurement);
procedure SetFontAngle(AFont: TFont; Angle: Extended);
var
logRec : TLogFont;
begin
GetObject(AFont.Handle, SizeOf(TLogFont), @logrec);
logrec.lfEscapement := Round(Angle*10);
AFont.Handle := CreateFontIndirect(logRec);
end;
var
ATextObject: TGmTextObject;
begin
x := ConvertValue(x, GmMeasurement, GmUnits) + GetLeft;
y := ConvertValue(y, GmMeasurement, GmUnits) + GetTop;
// create a text object and set its values...
ATextObject := TGmTextObject.Create;
ATextObject.X := Round(X);
ATextObject.Y := Round(Y);
ATextObject.Caption := AText;
ATextObject.Brush := BrushToGmBrush(FBrush);
SetFontAngle(FFont, Angle);
ATextObject.Font := FontToGmFont(FFont);
FPage.AddObject(ATextObject);
end;
procedure TGmCanvas.RoundRect(x, y, x2, y2, x3, y3: Extended; GmMeasurement: TGmMeasurement);
var
ARoundRectShape: TGmRoundRectShape;
begin
// Create a round-rect object and add it to the page objects list...
ARoundRectShape := TGmRoundRectShape.Create;
ARoundRectShape.Brush := BrushToGmBrush(FBrush);
ARoundRectShape.Pen := PenToGmPen(FPen);
ARoundRectShape.X := Round(ConvertValue(x, GmMeasurement, GmUnits)) + GetLeft;
ARoundRectShape.Y := Round(ConvertValue(y, GmMeasurement, GmUnits)) + GetTop;
ARoundRectShape.X2 := Round(ConvertValue(x2, GmMeasurement, GmUnits)) + GetLeft;
ARoundRectShape.Y2 := Round(ConvertValue(y2, GmMeasurement, GmUnits)) + GetTop;
ARoundRectShape.X3 := Round(ConvertValue(x3, GmMeasurement, GmUnits));
ARoundRectShape.Y3 := Round(ConvertValue(y3, GmMeasurement, GmUnits));
FPage.AddObject(ARoundRectShape);
end;
procedure TGmCanvas.StretchDraw(x,y, x2, y2: Extended; AGraphic: TGraphic; GmMeasurement: TGmMeasurement);
var
AObject: TGmGraphicObject;
//Ppi: Integer;
ConvertBmp: TBitmap;
//Unused: Extended;
ARect: TRect;
begin
// create a new graphic object and set its values...
if Assigned(AGraphic) then
begin
ARect.Left := Round(ConvertValue(x, GmMeasurement, GmUnits)) + GetLeft;
ARect.Top := Round(ConvertValue(y, GmMeasurement, GmUnits)) + GetTop;
ARect.Right := Round(ConvertValue(x2, GmMeasurement, GmUnits)) + GetLeft;
ARect.Bottom := Round(ConvertValue(y2, GmMeasurement, GmUnits)) + GetTop;
AObject := TGmGraphicObject.Create;
AObject.CopyMode := FCopyMode;
AObject.SetBounds(ARect.Left, ARect.Top, ARect.Right, ARect.Bottom);
// create the picture and bitmap objects...
if (AGraphic is TIcon) then
begin
ConvertBmp := TBitmap.Create;
ConvertBmp.HandleType := bmDIB;
ConvertBmp.Height := AGraphic.Height;
ConvertBmp.Width := AGraphic.Width;
ConvertBmp.Canvas.Draw(0, 0, AGraphic);
AObject.Bitmap := TBitmap.Create;
AObject.Bitmap := ConvertBmp;
ConvertBmp.Free;
end
else
if (AGraphic is TBitmap) then
AObject.Bitmap := (AGraphic as TBitmap)
else
if (AGraphic is TMetafile) then
begin
AObject.Metafile := TMetafile.Create;
AObject.Metafile.Assign(AGraphic);
end;
// add the graphic object to the current page...
FPage.AddObject(AObject);
end;
end;
function TGmCanvas.TextBox(x, y, x2, y2: Extended; AText: string;
Alignment: TAlignment; Draw: Boolean; GmMeasurement: TGmMeasurement): Extended;
begin
Result := TextBoxExt(X, Y, X2, Y2, AText, Alignment, gmTop, Draw, GmMeasurement);
end;
function TGmCanvas.TextBoxExt(x, y, x2, y2: Extended; AText: string;
Alignment: TAlignment; VertAlignment: TGmVertAlignment; Draw: Boolean; GmMeasurement: TGmMeasurement): Extended;
var
ATextBox: TGmTextBoxObject;
CalcRect: TRect;
Ppi: integer;
TempVal: TGmValue;
begin
// create a textbox object and set its values...
x := ConvertValue(x, GmMeasurement, GmUnits) + GetLeft;
y := ConvertValue(y, GmMeasurement, GmUnits) + GetTop;
x2 := ConvertValue(x2, GmMeasurement, GmUnits) + GetLeft;
y2 := ConvertValue(y2, GmMeasurement, GmUnits) + GetTop;
//Unused := 0;
ATextBox := TGmTextBoxObject.Create;
// create the textBox...
//AObject.X := Round(X);
//AObject.Y := Round(Y);
//AObject.X2 := Round(X2);
if (AText = '') and (Y2 = 0) then Y2 := Y;
//if Y2 > 0 then
//AObject.Y2 := Round(Y2);
ATextBox.Caption := AText;
ATextBox.Alignment := Alignment;
ATextBox.VertAlignment := Ord(VertAlignment);
ATextBox.Brush := BrushToGmBrush(FBrush);
ATextBox.Font := FontToGmFont(FFont{, 0});
ATextBox.Pen := PenToGmPen(FPen);
//ATextBox.Page := FPreview.CurrentPage;
if Y2 = 0 then
begin
// calculate the height of the textBox...
Ppi := Screen.PixelsPerInch;
CalcRect.Left := Round(ConvertValue(x, GmUnits, GmPixels));
CalcRect.Top := Round(ConvertValue(y, GmUnits, GmPixels));
CalcRect.Right := Round(ConvertValue(x2, GmUnits, GmPixels));
// this doesn't actually draw the text - it just returns the height of the text
// as screen pixels...
FTempCanvas.Lock;
try
FTempCanvas.Font := FFont;
Windows.DrawText(FTempCanvas.Handle,
PChar(AText),
Length(AText),
CalcRect,
DT_WORDBREAK + DT_CALCRECT);
finally
FTempCanvas.Unlock;
end;
TempVal := TGmValue.Create;
try
TempVal.AsInches := CalcRect.Bottom / Ppi;
Y2 := TempVal.AsUnits;
finally
TempVal.Free;
end;
end;
//if FCoordsRelative <> fromPage then
//ConvertCoords(X, Y, X2, Y2, Unused, Unused, Unused, Unused);
ATextBox.X := Round(x);
ATextBox.Y := Round(y);
ATextBox.X2 := Round(x2);
ATextBox.Y2 := Round(y2);
Result := ConvertValue(ATextBox.y2 - ATextBox.y, GmUnits, GmMeasurement) + GetTop;
if Draw then
begin
// add the textbox object to the current page...
FPage.AddObject(ATextBox);
{FLastObject := AObject;
if Assigned(FPreview.FOnCanvasChange) then
FPreview.FOnCanvasChange(Self); }
end
else
ATextBox.Free;
end;
procedure TGmCanvas.TextExtent(AText : string; var AWidth, AHeight: TGmValue);
begin
AWidth := FValue1;
AHeight := FValue2;
FValue1.AsUnits := TextWidth(AText).AsUnits;
FValue2.AsUnits := TextHeight(AText).AsUnits;
end;
{$IFNDEF BCB}
procedure TGmCanvas.TextOut(x, y: Extended; AText: string; GmMeasurement: TGmMeasurement);
begin
// I have added a TextOutLeft method because C++ seems to cause a fuss about using
// the standard TextOut method !? This will not alter any existing Delphi code...
TextOutLeft(x, y, AText, GmMeasurement);
end;
{$ENDIF}
procedure TGmCanvas.TextOutLeft(x, y: Extended; AText: string; GmMeasurement: TGmMeasurement);
var
ATextObject: TGmTextObject;
begin
// Create a rectangle object and add it to the page objects list...
ATextObject := TGmTextObject.Create;
ATextObject.Font := FontToGmFont(FFont{, 0});
ATextObject.Brush := BrushToGmBrush(FBrush);
ATextObject.X := Round(ConvertValue(x, GmMeasurement, GmUnits)) + GetLeft;
ATextObject.Y := Round(ConvertValue(y, GmMeasurement, GmUnits)) + GetTop;
ATextObject.Caption := AText;
FPage.Add(ATextObject);
end;
procedure TGmCanvas.TextOutRight(x, y: Extended; AText: string; GmMeasurement: TGmMeasurement);
var
ALeft,ATop, AWidth: Integer;
begin
// draw right aligned text with its right side aligned to the X parameter...
ALeft := Round(ConvertValue(x, GmMeasurement, GmUnits)) + GetLeft;
ATop := Round(ConvertValue(y, GmMeasurement, GmUnits)) + GetTop;
AWidth := Textwidth(AText).AsUnits;
TextOutLeft(ALeft-AWidth, ATop, AText, GmUnits);
end;
//------------------------------------------------------------------------------
// Overloaded canvas methods...
{$IFNDEF VER100}
procedure TGmCanvas.Ellipse(ARect: TGmRect; GmMeasurement: TGmMeasurement);
begin
Ellipse(ARect.Left, ARect.Top, ARect.Right, ARect.Bottom, GmMeasurement);
end;
procedure TGmCanvas.FillRect(ARect: TGmRect; GmMeasurement: TGmMeasurement);
begin
Ellipse(ARect.Left, ARect.Top, ARect.Right, ARect.Bottom, GmMeasurement);
end;
procedure TGmCanvas.Line(ARect: TGmRect; GmMeasurement: TGmMeasurement);
begin
Line(ARect.Left, ARect.Top, ARect.Right, ARect.Bottom, GmMeasurement);
end;
procedure TGmCanvas.LineExt(ARect: TGmRect; LineWidth: integer; GmMeasurement: TGmMeasurement);
begin
LineExt(ARect.Left, ARect.Top, ARect.Right, ARect.Bottom, LineWidth, GmMeasurement);
end;
procedure TGmCanvas.Rectangle(ARect: TGmRect; GmMeasurement: TGmMeasurement);
begin
Rectangle(ARect.Left, ARect.Top, ARect.Right, ARect.Bottom, GmMeasurement);
end;
procedure TGmCanvas.RoundRect(ARect: TGmRect; x3, y3: Extended; GmMeasurement: TGmMeasurement);
begin
RoundRect(ARect.Left, ARect.Top, ARect.Right, ARect.Bottom, x3, y3, GmMeasurement);
end;
function TGmCanvas.TextBox(ARect: TGmRect; AText: string;
Alignment: TAlignment; Draw: Boolean; GmMeasurement: TGmMeasurement): Extended;
begin
Result := TextBox(ARect.Left, ARect.Top, ARect.Right, ARect.Bottom, AText, Alignment, Draw, GmMeasurement);
end;
function TGmCanvas.TextBoxExt(ARect: TGmRect; AText: string;
Alignment: TAlignment; VertAlignment: TGmVertAlignment; Draw: Boolean; GmMeasurement: TGmMeasurement): Extended;
begin
Result := TextBoxExt(ARect.Left, ARect.Top, ARect.Right, ARect.Bottom, AText, Alignment, VertAlignment, Draw, GmMeasurement);
end;
// methods which use the default measurmement parameter...
procedure TGmCanvas.Arc(x1, y1, x2, y2, x3, y3, x4, y4: Extended);
begin
Arc(x1, y1, x2, y2, x3, y3, x4, y4, FDefaultMeasurement);
end;
procedure TGmCanvas.Chord(x1, y1, x2, y2, x3, y3, x4, y4: Extended);
begin
Chord(x1, y1, x2, y2, x3, y3, x4, y4, FDefaultMeasurement);
end;
procedure TGmCanvas.Draw(x,y: double; AGraphic: TGraphic; Scale: Extended);
begin
Draw(x, y, AGraphic, Scale, FDefaultMeasurement);
end;
procedure TGmCanvas.Ellipse(x, y, x2, y2: Extended);
begin
Ellipse(x, y, x2, y2, FDefaultMeasurement);
end;
procedure TGmCanvas.FillRect(x, y, x2, y2: Extended);
begin
FillRect(x, y, x2, y2, FDefaultMeasurement);
end;
procedure TGmCanvas.FloatOut(x, y, AValue: Extended; Format: string);
begin
FloatOut(x, y, AValue, Format, FDefaultMeasurement);
end;
procedure TGmCanvas.Line(x, y, x2, y2: Extended);
begin
Line(x, y, x2, y2, FDefaultMeasurement);
end;
procedure TGmCanvas.LineExt(x, y, x2, y2: Extended; LineWidth: Integer);
begin
LineExt(x, y, x2, y2, LineWidth, FDefaultMeasurement);
end;
procedure TGmCanvas.Pie(x, y, x2, y2, x3, y3, x4, y4: Extended);
begin
Pie(x, y, x2, y2, x3, y3, x4, y4, FDefaultMeasurement);
end;
procedure TGmCanvas.RotateOut(x, y, Angle: Extended; AText: string);
begin
RotateOut(x, y, Angle, AText, FDefaultMeasurement);
end;
{$IFNDEF BCB}
procedure TGmCanvas.TextOut(x, y: Extended; AText: string);
begin
TextOut(x, y, AText, FDefaultMeasurement);
end;
{$ENDIF}
procedure TGmCanvas.TextOutLeft(x, y: Extended; AText: string);
begin
TextOutLeft(x, y, AText, FDefaultMeasurement);
end;
procedure TGmCanvas.TextOutRight(x, y: Extended; AText: string);
begin
TextOutRight(x, y, AText, FDefaultMeasurement);
end;
function TGmCanvas.TextBox(x, y, x2, y2: Extended; AText: string;
Alignment: TAlignment; Draw: Boolean): Extended;
begin
Result := TextBox(x, y, x2, y2, AText, Alignment, Draw, FDefaultMeasurement);
end;
function TGmCanvas.TextBoxExt(x, y, x2, y2: Extended; AText: string;
Alignment: TAlignment; VertAlignment: TGmVertAlignment; Draw: Boolean): Extended;
begin
Result := TextBoxExt(x, y, x2, y2, AText, Alignment, VertAlignment, Draw, FDefaultMeasurement);
end;
procedure TGmCanvas.Rectangle(x, y, x2, y2: Extended);
begin
Rectangle(x, y, x2, y2, FDefaultMeasurement);
end;
procedure TGmCanvas.RoundRect(x, y, x2, y2, x3, y3: Extended);
begin
RoundRect(x, y, x2, y2, x3, y3, FDefaultMeasurement);
end;
procedure TGmCanvas.Polygon(Points: array of TGmPoint);
begin
PolyGon(Points, FDefaultMeasurement);
end;
procedure TGmCanvas.PolyLine(Points: array of TGmPoint);
begin
PolyLine(Points, FDefaultMeasurement);
end;
procedure TGmCanvas.PolyBezier(Points: array of TGmPoint);
begin
PolyBezier(Points, FDefaultMeasurement);
end;
procedure TGmCanvas.StretchDraw(x, y, x2, y2: Extended; AGraphic: TGraphic);
begin
StretchDraw(x, y, x2, y2, AGraphic, FDefaultMeasurement);
end;
{$ENDIF}
procedure TGmCanvas.SavePen(var Message: TMessage);
begin
FSavedPen.Assign(FPen);
end;
procedure TGmCanvas.RestorePen(var Message: TMessage);
begin
FPen.Assign(FSavedPen);
end;
procedure TGmCanvas.SaveBrush(var Message: TMessage);
begin
FSavedBrush.Assign(FBrush);
end;
procedure TGmCanvas.RestoreBrush(var Message: TMessage);
begin
FBrush.Assign(FSavedBrush);
end;
//------------------------------------------------------------------------------
// *** TGmPage ***
constructor TGmPage.Create(APreview: TGmPreview);
begin
inherited Create;
FPreview := APreview;
FMetafile := TMetafile.Create;
FOrientation := FPreview.Orientation;
//FPaperSize := FPreview.PaperSize;
end;
destructor TGmPage.Destroy;
begin
Clear;
FMetafile.Free;
inherited Destroy;
end;
{procedure TGmPage.Add(AObject: TGmBaseObject);
var
NewObj: PGmPageObject;
begin
New(NewObj);
NewObj.AObject := AObject;
Inc(FCount);
if FStartObject <> nil then
begin
FObjects.NextObj := NewObj;
NewObj.PrevObj := FObjects;
FObjects := NewObj;
end
else
begin
FStartObject := NewObj;
FObjects := NewObj;
FObjects.PrevObj := nil;
end;
NewObj.NextObj := nil;
end;}
function TGmPage.GetObject(AIndex: integer): TGmBaseObject;
{var
CurrentObj: PGmPageObject;
ICount: integer; }
begin
{CurrentObj := FStartObject;
for ICount := 0 to AIndex-1 do
CurrentObj := CurrentObj.NextObj;
Result := CurrentObj.AObject; }
{ TODO : }
Result := TGmBaseObject(Self[AIndex]);
end;
procedure TGmPage.SetObject(AIndex: integer; AObject: TGmBaseObject);
{var
CurrentObj: PGmPageObject;
ICount: integer;}
begin
{for ICount := 0 to AIndex do
CurrentObj := CurrentObj.NextObj;
CurrentObj.AObject := AObject; }
Self[AIndex] := AObject;
end;
procedure TGmPage.SetOrientation(AOrientation: TGmOrientation);
begin
if FOrientation <> AOrientation then
begin
FOrientation := AOrientation;
DrawPage;
FPreview.MessageToControls(GM_UPDATE_PREVIEW, 0, 0);
FPreview.MessageToControls(GM_PAGE_ORIENTATION_CHANGED, PageNum, 0);
if Assigned(FPreview.OnChangePageOrientation) then
FPreview.OnChangePageOrientation(Self, FPageNum, FOrientation);
FPreview.PositionPage;
//SetPaperSize(FPaperSize);
end;
end;
procedure TGmPage.AddObject(AObject: TGmBaseObject);
begin
// Add the object to the page objects list...
Add(AObject);
end;
procedure TGmPage.Clear;
var
ICount: integer;
begin
// clear all objects from the page...
{ TODO : }
for ICount := Count-1 downto 0 do
TGmBaseObject(Self[ICount]).Free;
inherited Clear;
end;
procedure TGmPage.DrawPage;//(InchWidth, InchHeight: Extended);
var
ICount: integer;
ACanvas: TMetafileCanvas;
Rgn: HRGN;
W, H: Extended;
PagePixelsWidth,
PagePixelsHeight: integer;
begin
// re-create the page metafile by looping through and redrawing each of the
// objects...
FMetafile.Clear;
case FOrientation of
gmPortrait:
begin
W := MinExt(FInchWidth, FInchHeight);
H := MaxExt(FInchWidth, FInchHeight);
end
else
begin
W := MaxExt(FInchWidth, FInchHeight);
H := MinExt(FInchWidth, FInchHeight);
end;
end;
PagePixelsWidth := Round(W * ScreenPpi);
PagePixelsHeight := Round(H * ScreenPpi);
FMetafile.Width := PagePixelsWidth;
FMetafile.Height := PagePixelsHeight;
ACanvas := TMetafileCanvas.Create(FMetafile, 0);
if FPreview.Margins.ClipMargins then
Rgn := CreateRectRgn(FPreview.Margins.Left.AsPixels[ScreenPpi],
FPreview.Margins.Top.AsPixels[ScreenPpi],
PagePixelsWidth - FPreview.Margins.Right.AsPixels[ScreenPpi],
PagePixelsHeight - FPreview.Margins.Bottom.AsPixels[ScreenPpi])
else
Rgn := CreateRectRgn(0,
0,
PagePixelsWidth,
PagePixelsHeight);
SelectClipRgn(ACanvas.Handle, Rgn);
try
for ICount := 0 to Self.Count-1 do
begin
TGmBaseObject(GmObject[ICount]).Page := Self.PageNum;
TGmBaseObject(GmObject[ICount]).Draw(ACanvas, FPreview, Point(0,0), 1);
end;
//Dec(PagePixelsWidth, FPreview.Shadow.Width);
//Dec(PagePixelsHeight, FPreview.Shadow.Width);
if FPreview.Header.Visible then
FPreview.Header.Draw(ACanvas, FPreview.Margins, Rect(0,0,PagePixelsWidth, PagePixelsHeight), FPageNum, 1);
if FPreview.Footer.Visible then
FPreview.Footer.Draw(ACanvas, FPreview.Margins, Rect(0,0,PagePixelsWidth, PagePixelsHeight), FPageNum, 1);
finally
ACanvas.Free;
end;
FPreview.MessageToControls(GM_PAGE_UPDATED, PageNum, 0);
end;
procedure TGmPage.LoadFromStream(AStream: TStream);
function CreateGmObject(FObjectID: integer): TGmBaseObject;
begin
case FObjectID of
GM_GRAPHIC_ID : Result := TGmGraphicObject.Create;
GM_LINE_ID : Result := TGmLineObject.Create;
GM_TEXT_ID : Result := TGmTextObject.Create;
GM_TEXTBOX_ID : Result := TGmTextBoxObject.Create;
GM_ELLIPSE_ID : Result := TGmEllipseShape.Create;
GM_RECTANGLE_ID : Result := TGmRectangleShape.Create;
GM_ROUNDRECT_ID : Result := TGmRoundRectShape.Create;
GM_ARC_ID : Result := TGmArcShape.Create;
GM_CHORD_ID : Result := TGmChordShape.Create;
GM_PIE_ID : Result := TGmPieShape.Create;
{$IFNDEF VER100}
GM_POLYGON_ID : Result := TGmPolygonObject.Create;
GM_POLYLINE_ID : Result := TGmPolyLineObject.Create;
GM_POLYBEZIER_ID: Result := TGmPolyBezierObject.Create;
{$ENDIF}
else
Result := nil;
end;
end;
var
GmStream: TGmExtStream;
NumObjects: integer;
ICount: integer;
AObjectID: integer;
NewObject: TGmBaseObject;
begin
GmStream := TGmExtStream.Create;
try
GmStream.LoadFromStream(AStream);
FOrientation := TGmOrientation(GmStream.ReadInteger);
NumObjects := GmStream.ReadInteger;
for ICount := 1 to NumObjects do
begin
GmStream.ReadBuffer(AObjectID, SizeOf(AObjectID));
NewObject := CreateGmObject(AObjectID);
if Assigned(NewObject) then
begin
AddObject(NewObject);
NewObject.LoadFromStream(GmStream);
end;
end;
finally
GmStream.Free;
end;
end;
procedure TGmPage.SaveToStream(AStream: TStream);
var
GmStream: TGmExtStream;
ICount: integer;
begin
GmStream := TGmExtStream.Create;
try
GmStream.WriteInteger(Ord(FOrientation));
GmStream.WriteInteger(Self.Count);
for ICount := 0 to Self.Count-1 do
begin
GmObject[ICount].SaveToStream(GmStream);
end;
finally
GmStream.SaveToStream(AStream);
GmStream.Free;
end;
end;
//------------------------------------------------------------------------------
// *** TGmPageList ***
constructor TGmPageList.Create(AOwner: TGmPreview);
begin
inherited Create;
FPreview := AOwner;
end;
destructor TGmPageList.Destroy;
begin
Clear;
inherited Destroy;
end;
function TGmPageList.GetPage(APageIndex: integer): TGmPage;
begin
Result := TGmPage(Self[APageIndex-1]);
end;
procedure TGmPageList.Repaginate;
var
ICount: integer;
begin
for ICount := 1 to Self.Count do
Page[ICount].FPageNum := ICount;
end;
procedure TGmPageList.SetPage(APageIndex: integer; APage: TGmPage);
begin
Self[APageIndex-1] := APage;
end;
function TGmPageList.AddPage: TGmPage;
var
NewPage: TGmPage;
begin
// add a page to the end of the list...
NewPage := TGmPage.Create(FPreview);
Self.Add(NewPage);
Result := NewPage;
//Result.Capacity := 1000;
Result.FPageNum := Count;
//Repaginate;
end;
procedure TGmPageList.Clear;
var
ICount: integer;
begin
// clear all pages from the list...
for ICount := Self.Count-1 downto 0 do
TGmPage(Self[ICount]).Free;
inherited Clear;
if Assigned(FPreview.OnClear) then FPreview.OnClear(FPreview);
end;
procedure TGmPageList.DeletePage(APage: integer);
begin
TGmPage(Self[APage-1]).Free;
Self.Delete(APage-1);
Repaginate;
if Assigned(FPreview.OnDeletePage) then FPreview.OnDeletePage(FPreview);
end;
//------------------------------------------------------------------------------
// *** TGmMargins ***
constructor TGmMargins.Create(AOwner: TGmPreview);
begin
inherited Create;
FPreview := AOwner;
//FPaintBox := AOwner.FPageImage;
// set up the pen objects...
FPen := TPen.Create;
FPen.Color := clSilver;
FPen.Style := psDot;
FPen.OnChange := PenChange;
FPrinterPen := TPen.Create;
FPrinterPen.Assign(FPen);
FPrinterPen.OnChange := PenChange;
FBottom := TGmValue.Create;
FLeft := TGmValue.Create;
FRight := TGmValue.Create;
FTop := TGmValue.Create;
// set the default values...
FBottom.AsMillimeters := 25;
FLeft.AsMillimeters := 15;
FRight.AsMillimeters := 15;
FTop.AsMillimeters := 20;
FVisible := False;
FShowPrintMargins := False;
FClipMargins := False;
FLeft.OnChange := MarginsChanged;
FTop.OnChange := MarginsChanged;
FRight.OnChange := MarginsChanged;
FBottom.OnChange := MarginsChanged;
end;
destructor TGmMargins.Destroy;
begin
FBottom.Free;
FLeft.Free;
FRight.Free;
FTop.Free;
FPen.Free;
FPen := nil;
FPrinterPen.Free;
FPrinterPen := nil;
inherited Destroy;
end;
function TGmMargins.AreMarginsValid: Boolean;
var
APreview: TGmPreview;
begin
APreview := TGmPreview(FPreview);
Result := (FLeft.AsUnits >= APreview.GmPrinter.PrinterMargins.Left.AsUnits) and
(FTop.AsUnits >= APreview.GmPrinter.PrinterMargins.Top.AsUnits) and
(FRight.AsUnits >= APreview.GmPrinter.PrinterMargins.Right.AsUnits) and
(FBottom.AsUnits >= APreview.GmPrinter.PrinterMargins.Bottom.AsUnits);
end;
procedure TGmMargins.Assign(Source: TPersistent);
var
AMargins: TGmMargins;
begin
AMargins := (Source as TGmMargins);
FLeft.FValue := AMargins.FLeft.FValue;
FTop.FValue := AMargins.FTop.FValue;
FRight.FValue := AMargins.FRight.FValue;
FBottom.FValue := AMargins.FBottom.FValue;
FVisible := AMargins.Visible;
FShowPrintMargins := AMargins.FShowPrintMargins;
FPen.Assign(AMargins.Pen);
FPrinterPen.Assign(AMargins.PrinterMarginPen);
if Assigned(FPaintBox) then FPaintBox.Invalidate;
end;
{procedure TGmMargins.LoadFromValues(AValues: TObject);
begin
{with (AValues as TGmValueList) do
begin
Left.AsUnits := ValueInt[C_MARGIN_LEFT];
Top.AsUnits := ValueInt[C_MARGIN_TOP];
Right.AsUnits := ValueInt[C_MARGIN_RIGHT];
Bottom.AsUnits := ValueInt[C_MARGIN_BOTTOM];
Visible := Boolean(ValueInt[C_MARGIN_VISIBLE]);
Pen.Color := ValueInt[C_PEN_COLOR];
Pen.Style := TPenStyle(ValueInt[C_PEN_STYLE]);
Pen.Width := ValueInt[C_PEN_WIDTH];
ShowPrinterMargins := False;
end
end;}
procedure TGmMargins.LoadFromStream(AStream: TStream);
var
GmStream: TGmExtStream;
begin
GmStream := TGmExtStream.Create;
try
GmStream.LoadFromStream(AStream);
FLeft.AsUnits := GmStream.ReadInteger;
FTop.AsUnits := GmStream.ReadInteger;
FRight.AsUnits := GmStream.ReadInteger;
FBottom.AsUnits := GmStream.ReadInteger;
FVisible := GmStream.ReadBoolean;
FShowPrintMargins := GmStream.ReadBoolean;
//GmPenToPen(FPen, GmStream.ReadPen);
//GmPenToPen(FPrinterPen, GmStream.ReadPen);
FClipMargins := GmStream.ReadBoolean;
finally
GmStream.Free;
end;
end;
procedure TGmMargins.SaveToStream(AStream: TStream);
var
GmStream: TGmExtStream;
begin
GmStream := TGmExtStream.Create;
try
GmStream.WriteInteger(FLeft.AsUnits);
GmStream.WriteInteger(FTop.AsUnits);
GmStream.WriteInteger(FRight.AsUnits);
GmStream.WriteInteger(FBottom.AsUnits);
GmStream.WriteBoolean(FVisible);
GmStream.WriteBoolean(FShowPrintMargins);
//GmStream.WritePen(PenToGmPen(FPen));
//GmStream.WritePen(PenToGmPen(FPrinterPen));
GmStream.WriteBoolean(FClipMargins);
finally
GmStream.SaveToStream(AStream);
GmStream.Free;
end;
end;
procedure TGmMargins.UsePrinterMargins;
var
APreview: TGmPreview;
begin
APreview := TGmPreview(FPreview);
FLeft.AsUnits := APreview.GmPrinter.PrinterMargins.Left.AsUnits;
FTop.AsUnits := APreview.GmPrinter.PrinterMargins.Top.AsUnits;
FRight.AsUnits := APreview.GmPrinter.PrinterMargins.Right.AsUnits;
FBottom.AsUnits := APreview.GmPrinter.PrinterMargins.Bottom.AsUnits;
APreview.UpdatePreview;
end;
procedure TGmMargins.SetClipMargins(AValue: Boolean);
begin
if FClipMargins <> AValue then
begin
FClipMargins := AValue;
TGmPreview(FPreview).UpdatePreview;
end;
end;
procedure TGmMargins.PenChange(Sender: TObject);
begin
if Assigned(FPaintBox) then FPaintBox.Invalidate;
end;
procedure TGmMargins.SetShowPrinterMargins(AValue: Boolean);
begin
FShowPrintMargins := AValue;
if Assigned(FPaintBox) then FPaintBox.Invalidate;
end;
procedure TGmMargins.SetVisible(AValue: Boolean);
begin
FVisible := AValue;
if Assigned(FPaintBox) then
FPaintBox.Invalidate;
end;
procedure TGmMargins.MarginsChanged(AObject: TObject);
begin
if Assigned(FPreview) then
begin
FPreview.MessageToControls(GM_USER_MARGINS_CHANGED, 0, 0);
if Assigned(FPreview.FOnChangeMargins) then FPreview.OnChangeMargins(Self);
end;
end;
//------------------------------------------------------------------------------
constructor TGmPageImage.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FValue1 := TGmValue.Create;
FValue2 := TGmValue.Create;
Screen.Cursors[crZoomIn] := LoadCursor(HInstance, 'ZoomIn');
Screen.Cursors[crZoomOut] := LoadCursor(HInstance, 'ZoomOut');
FWidthInches := 8.2;
FHeightInches := 11.6;
Gutter := 30;
end;
destructor TGmPageImage.Destroy;
begin
FValue1.Free;
FValue2.Free;
inherited Destroy;
end;
procedure TGmPageImage.CMMouseLeave (var Message: TMessage);
begin
(Owner as TGmPreview).StopPanning;
end;
procedure TGmPageImage.MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
var
APreview: TGmPreview;
begin
inherited;
if (X > Gutter) and (Y > Gutter) and
(X < (Width - Gutter)) and (Y < (Height-Gutter)) then
begin
APreview := (Owner as TGmPreview);
APreview.MouseDown(Button, Shift, Left+X, Top+Y);
if Assigned(APreview.OnPageMouseDown) then
begin
FValue1.AsPixels[ScreenPpi] := Round((X-Gutter) / Scale);
FValue2.AsPixels[ScreenPpi] := Round((Y-Gutter) / Scale);
APreview.OnPageMouseDown(APreview, Button, Shift, FValue1, FValue2);
end;
end;
end;
procedure TGmPageImage.MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
var
APreview: TGmPreview;
begin
inherited;
if (X > Gutter) and (Y > Gutter) and
(X < (Width - Gutter)) and (Y < (Height-Gutter)) then
begin
APreview := (Owner as TGmPreview);
APreview.MouseUp(Button, Shift, Left+X, Top+Y);
if Assigned(APreview.OnPageMouseUp) then
begin
FValue1.AsPixels[ScreenPpi] := Round((X-Gutter) / Scale);
FValue2.AsPixels[ScreenPpi] := Round((Y-Gutter) / Scale);
APreview.OnPageMouseUp(APreview, Button, Shift, FValue1, FValue2);
end;
end;
end;
procedure TGmPageImage.MouseMove(Shift: TShiftState; X, Y: Integer);
var
APreview: TGmPreview;
begin
inherited;
if (X > Gutter) and (Y > Gutter) and
(X < (Width - Gutter)) and (Y < (Height-Gutter)) then
begin
APreview := (Owner as TGmPreview);
APreview.MouseMove(Shift, Left+X, Top+Y);
if Assigned(APreview.OnPageMouseMove) then
begin
FValue1.AsPixels[ScreenPpi] := Round((X-Gutter) / Scale);
FValue2.AsPixels[ScreenPpi] := Round((Y-Gutter) / Scale);
APreview.OnPageMouseMove(APreview, Shift, FValue1, FValue2);
end;
end;
end;
procedure TGmPageImage.Paint;
var
Margins: TGmMargins;
Ppi: integer;
APreview: TGmPreview;
ShadowWidth: integer;
begin
inherited;
if Assigned(FMargins) then
begin
Margins := TGmMargins(FMargins);
APreview := TGmPreview(Owner);
ShadowWidth := APreview.Shadow.Width;
if Margins.Visible then
begin
// paint the margins...
with Canvas do
begin
Ppi := Screen.PixelsPerInch;
Brush.Style := bsClear;
Pen.Assign(Margins.Pen);
Rectangle(Gutter+(Round(Margins.Left.AsPixels[Ppi]*Scale)),
Gutter+(Round(Margins.Top.AsPixels[Ppi]*Scale)),
(Width-(Round(Margins.Right.AsPixels[Ppi]*Scale))-(Gutter))-ShadowWidth,
(Height-(Round(Margins.Bottom.AsPixels[Ppi]*Scale))-(Gutter))-ShadowWidth);
end;
end;
if Margins.ShowPrinterMargins then
begin
// paint the margins...
with Canvas do
begin
Brush.Style := bsClear;
Ppi := Screen.PixelsPerInch;
Brush.Style := bsClear;
Pen.Assign(Margins.Pen);
Rectangle(Gutter+ (Round(APreview.GmPrinter.PrinterMargins.Left.AsPixels[Ppi]*Scale)),
Gutter+ (Round(APreview.GmPrinter.PrinterMargins.Top.AsPixels[Ppi]*Scale)),
Width- (Round(APreview.GmPrinter.PrinterMargins.Right.AsPixels[Ppi]*Scale))-(Gutter)-ShadowWidth,
Height- (Round(APreview.GmPrinter.PrinterMargins.Bottom.AsPixels[Ppi]*Scale))-(Gutter)-ShadowWidth);
end;
end;
end;
end;
procedure TGmPageImage.SetHeightInches(AValue: Extended);
begin
FHeightInches := AValue;
RecalculateSize;
end;
procedure TGmPageImage.SetWidthInches(AValue: Extended);
begin
FWidthInches := AValue;
RecalculateSize;
end;
procedure TGmPageImage.RecalculateSize;
var
Ppi: integer;
begin
Ppi := Screen.PixelsPerInch;
FPageWidth := Round(FScale*(FWidthInches * Ppi));
FPageHeight := Round(FScale*(FHeightInches * Ppi));
Width := FPageWidth + Gutter*2;
Height := FPageHeight + Gutter*2;
end;
procedure TGmPageImage.SetScale(AScale: Extended);
begin
FScale := AScale;
RecalculateSize;
end;
//------------------------------------------------------------------------------
// *** TGmHeaderFooterCaption ***
constructor TGmHeaderFooterCaption.Create(AOwner: TGmHeaderFooter);
begin
inherited Create;
FHeaderFooter := AOwner;
FFont := TFont.Create;
FFont.Size := 12;
FFont.Name := 'Arial';
FCaption := '';
Font.OnChange := FontChange;
end;
destructor TGmHeaderFooterCaption.Destroy;
begin
FFont.Free;
inherited Destroy;
end;
procedure TGmHeaderFooterCaption.Assign(Source: TPersistent);
begin
// ???
end;
procedure TGmHeaderFooterCaption.LoadFromStream(AStream: TStream);
var
GmStream: TGmExtStream;
begin
GmStream := TGmExtStream.Create;
try
GmStream.LoadFromStream(AStream);
GmFontToFont(FFont, GmStream.ReadFont, 1);
FCaption := GmStream.ReadStr;
finally
GmStream.Free;
end;
end;
procedure TGmHeaderFooterCaption.SaveToStream(AStream: TStream);
var
GmStream: TGmExtStream;
begin
GmStream := TGmExtStream.Create;
try
//GmStream.LoadFromStream(AStream);
GmStream.WriteFont(FontToGmFont(FFont));
GmStream.WriteStr(FCaption);
//GmFontToFont(FFont, GmStream.ReadFont);
//FCaption := GmStream.ReadStr;
finally
GmStream.SaveToStream(AStream);
GmStream.Free;
end;
end;
procedure TGmHeaderFooterCaption.FontChange(Sender: TObject);
begin
FHeaderFooter.RequestUpdate;
end;
procedure TGmHeaderFooterCaption.SetCaption(ACaption: string);
begin
FCaption := ACaption;
FHeaderFooter.RequestUpdate;
end;
procedure TGmHeaderFooterCaption.SetFont(AFont: TFont);
begin
FFont.Assign(AFont);
FHeaderFooter.RequestUpdate;
end;
//------------------------------------------------------------------------------
// *** TGmHeaderFooter ***
constructor TGmHeaderFooter.Create(AOwner: TGmPreview);
begin
inherited Create;
FState := hfCreating;
FPreview := AOwner;
FCanvas := FPreview.Canvas;
FCaptionLeft := TGmHeaderFooterCaption.Create(Self);
FCaptionCenter := TGmHeaderFooterCaption.Create(Self);
FCaptionRight := TGmHeaderFooterCaption.Create(Self);
FPen := TPen.Create;
Pen.OnChange := PenChange;
FHeight := TGmValue.Create;
FShowLine := True;
FVisible := True;
FState := hfIdle;
end;
destructor TGmHeaderFooter.Destroy;
begin
FState := hfDestroying;
FCaptionLeft.Free;
FCaptionCenter.Free;
FCaptionRight.Free;
FPen.Free;
FPen.OnChange := PenChange;
FHeight.Free;
FState := hfIdle;
inherited Destroy;
end;
procedure TGmHeaderFooter.Assign(Source: TPersistent);
begin
// ???
end;
procedure TGmHeaderFooter.LoadFromStream(AStream: TStream);
var
GmStream: TGmExtStream;
begin
GmStream := TGmExtStream.Create;
try
GmStream.LoadFromStream(AStream);
FShowLine := GmStream.ReadBoolean;
FVisible := GmStream.ReadBoolean;
FCaptionLeft.LoadFromStream(GmStream);
FCaptionCenter.LoadFromStream(GmStream);
FCaptionRight.LoadFromStream(GmStream);
GmPenToPen(FPen, GmStream.ReadPen);
finally
GmStream.Free;
end;
end;
procedure TGmHeaderFooter.SaveToStream(AStream: TStream);
var
GmStream: TGmExtStream;
begin
GmStream := TGmExtStream.Create;
try
GmStream.WriteBoolean(FShowLine);
GmStream.WriteBoolean(FVisible);
FCaptionLeft.SaveToStream(GmStream);
FCaptionCenter.SaveToStream(GmStream);
FCaptionRight.SaveToStream(GmStream);
GmStream.WritePen(PenToGmPen(FPen));
finally
GmStream.SaveToStream(AStream);
GmStream.Free;
end;
end;
procedure TGmHeaderFooter.SetCaptionLeft(ACaption: string);
begin
FCaptionLeft.Caption := ACaption;
end;
procedure TGmHeaderFooter.SetCaptionCenter(ACaption: string);
begin
FCaptionCenter.Caption := ACaption;
end;
procedure TGmHeaderFooter.SetCaptionRight(ACaption: string);
begin
FCaptionRight.Caption := ACaption;
end;
procedure TGmHeaderFooter.SetCaptionLeftFont(AFont: TFont);
begin
FCaptionLeft.Font.Assign(AFont);
end;
procedure TGmHeaderFooter.SetCaptionCenterFont(AFont: TFont);
begin
FCaptionCenter.Font.Assign(AFont);
end;
procedure TGmHeaderFooter.SetCaptionRightFont(AFont: TFont);
begin
FCaptionRight.Font.Assign(AFont);
end;
function TGmHeaderFooter.GetCaptionLeft: string;
begin
Result := FCaptionLeft.Caption;
end;
function TGmHeaderFooter.GetCaptionCenter: string;
begin
Result := FCaptionCenter.Caption;
end;
function TGmHeaderFooter.GetCaptionRight: string;
begin
Result := FCaptionRight.Caption;
end;
function TGmHeaderFooter.GetCaptionLeftFont: TFont;
begin
Result := FCaptionLeft.Font;
end;
function TGmHeaderFooter.GetCaptionCenterFont: TFont;
begin
Result := FCaptionCenter.Font;
end;
function TGmHeaderFooter.GetCaptionRightFont: TFont;
begin
Result := FCaptionRight.Font;
end;
procedure TGmHeaderFooter.PenChange(Sender: TObject);
begin
RequestUpdate;
end;
procedure TGmHeaderFooter.RequestUpdate;
begin
if FState = hfIdle then FPreview.MessageToControls(GM_UPDATE_PREVIEW, 0, 0);
end;
procedure TGmHeaderFooter.SetPen(APen: TPen);
begin
FPen.Assign(APen);
RequestUpdate;
end;
procedure TGmHeaderFooter.SetShowLine(AValue: Boolean);
begin
FShowLine := AValue;
RequestUpdate;
end;
procedure TGmHeaderFooter.SetVisible(AVisible: Boolean);
begin
FVisible := AVisible;
RequestUpdate;
end;
function TGmHeaderFooter.GetCaptionHeight(ACanvas: TCanvas; ACaption: string): integer;
var
{$IFNDEF VER100}
Metrics: tagTEXTMETRIC;
{$ELSE}
Metrics: TTextMetricA;
{$ENDIF}
begin
ACanvas.Lock;
with ACanvas do
try
GetTextMetrics(ACanvas.Handle, Metrics);
finally
Unlock;
end;
Result := Metrics.tmHeight;
end;
function TGmHeaderFooter.GetHeight: TGmValue;
begin
Result := FHeight;
if FVisible then
begin
FCanvas.FTempCanvas.Font := GetLargestFont;
Result.AsPixels[ScreenPpi] := GetCaptionHeight(FCanvas.FTempCanvas, ' ') + 2;
end
else
Result.AsUnits := 0;
end;
function TGmHeaderFooter.GetLargestFont: TFont;
begin
Result := FCaptionLeft.Font;
if (FCaptionCenter.Font.Size > Result.Size) then Result := FCaptionCenter.Font;
if (FCaptionRight.Font.Size > Result.Size) then Result := FCaptionRight.Font;
end;
//------------------------------------------------------------------------------
// *** TGmHeader ***
procedure TGmHeader.Draw(ACanvas: TCanvas; Margins: TGmMargins; PageRect: TRect;
APageNum: integer; Scale: Extended);
var
MarginRect: TRect;
CenterPoint: integer;
TextWidth: integer;
TextHeight: integer;
LastStyle: TBrushStyle;
Tokenized: string;
CanvasPpi: integer;
Offset: TPoint;
begin
Offset.x := 0;
Offset.y := 0;
FState := hfDrawing;
LastStyle := ACanvas.Brush.Style;
ACanvas.Brush.Style := bsClear;
CanvasPpi := PixelsPerInchX(ACanvas.Handle);
ACanvas.Font := (GetLargestFont);
MarginRect.Left := PageRect.Left + ((0-Offset.X) + Round(Scale * Margins.Left.AsPixels[CanvasPpi]));
MarginRect.Top := PageRect.Top + ((0-Offset.Y) + Round(Scale * Margins.Top.AsPixels[CanvasPpi]));
MarginRect.Right := PageRect.Right - ((0-Offset.X) + Round(Scale * Margins.Right.AsPixels[CanvasPpi]));
MarginRect.Bottom := MarginRect.Top + ((0-Offset.Y) + Round(Scale * Height.AsPixels[CanvasPpi]));
// left caption...
ACanvas.Font.Assign(FCaptionLeft.Font);
ACanvas.Font.PixelsPerInch := Round(CanvasPpi / Scale);
Tokenized := FPreview.Tokenize(FCaptionLeft.Caption, APageNum);
TextHeight := GetCaptionHeight(ACanvas, Tokenized);
ACanvas.TextOut(MarginRect.Left, (MarginRect.Bottom-TextHeight), Tokenized);
// center caption...
CenterPoint := (MarginRect.Right + MarginRect.Left) div 2;
ACanvas.Font.Assign(FCaptionCenter.Font);
ACanvas.Font.PixelsPerInch := Round(CanvasPpi / Scale);
Tokenized := FPreview.Tokenize(FCaptionCenter.Caption, APageNum);
TextHeight := GetCaptionHeight(ACanvas, Tokenized);
TextWidth := ACanvas.TextWidth(Tokenized);
ACanvas.TextOut(CenterPoint-(TextWidth div 2), (MarginRect.Bottom-TextHeight), Tokenized);
// right caption...
ACanvas.Font.Assign(FCaptionRight.Font);
ACanvas.Font.PixelsPerInch := Round(CanvasPpi / Scale);
Tokenized := FPreview.Tokenize(FCaptionRight.Caption, APageNum);
TextHeight := GetCaptionHeight(ACanvas, Tokenized);
TextWidth := ACanvas.TextWidth(Tokenized);
ACanvas.TextOut(MarginRect.Right-TextWidth, (MarginRect.Bottom-TextHeight), Tokenized);
if FShowLine then
begin
ACanvas.Pen.Assign(FPen);
ACanvas.MoveTo(MarginRect.Left, MarginRect.Bottom);
ACanvas.LineTo(MarginRect.Right, MarginRect.Bottom);
end;
ACanvas.Brush.Style := LastStyle;
FState := hfIdle;
end;
//------------------------------------------------------------------------------
// *** TGmFooter ***
procedure TGmFooter.Draw(ACanvas: TCanvas; Margins: TGmMargins; PageRect: TRect;
APageNum: integer; Scale: Extended);
var
MarginRect: TRect;
CenterPoint: integer;
TextWidth: integer;
LastStyle: TBrushStyle;
Tokenized: string;
CanvasPpi: integer;
Offset: TPoint;
begin
Offset.x := 0;
Offset.y := 0;
FState := hfDrawing;
LastStyle := ACanvas.Brush.Style;
ACanvas.Brush.Style := bsClear;
CanvasPpi := PixelsPerInchX(ACanvas.Handle);
ACanvas.Font := (GetLargestFont);
MarginRect.Left := PageRect.Left + ((0-Offset.X) + Round(Scale * Margins.Left.AsPixels[CanvasPpi]));
MarginRect.Top := PageRect.Bottom - Round(Scale * (Height.AsPixels[CanvasPpi]+Margins.Bottom.AsPixels[CanvasPpi]));
MarginRect.Right := PageRect.Right - ((0-Offset.X) + Round(Scale * Margins.Right.AsPixels[CanvasPpi]));
MarginRect.Bottom := PageRect.Bottom - Round(Scale * (Margins.Bottom.AsPixels[CanvasPpi]));
// left caption...
ACanvas.Font.Assign(FCaptionLeft.Font);
ACanvas.Font.PixelsPerInch := Round(CanvasPpi / Scale);
Tokenized := FPreview.Tokenize(FCaptionLeft.Caption, APageNum);
ACanvas.TextOut(MarginRect.Left, (MarginRect.Top), Tokenized);
// center caption...
CenterPoint := (MarginRect.Right + MarginRect.Left) div 2;
ACanvas.Font.Assign(FCaptionCenter.Font);
ACanvas.Font.PixelsPerInch := Round(CanvasPpi / Scale);
Tokenized := FPreview.Tokenize(FCaptionCenter.Caption, APageNum);
TextWidth := ACanvas.TextWidth(Tokenized);
ACanvas.TextOut(CenterPoint-(TextWidth div 2), (MarginRect.Top), Tokenized);
// right caption...
ACanvas.Font.Assign(FCaptionRight.Font);
ACanvas.Font.PixelsPerInch := Round(CanvasPpi / Scale);
Tokenized := FPreview.Tokenize(FCaptionRight.Caption, APageNum);
TextWidth := ACanvas.TextWidth(Tokenized);
ACanvas.TextOut(MarginRect.Right-TextWidth, (MarginRect.Top), Tokenized);
if FShowLine then
begin
ACanvas.Pen.Assign(FPen);
ACanvas.MoveTo(MarginRect.Left, MarginRect.Top);
ACanvas.LineTo(MarginRect.Right, MarginRect.Top);
end;
ACanvas.Brush.Style := LastStyle;
FState := hfIdle;
end;
//------------------------------------------------------------------------------
constructor TGmOptions.Create;
begin
inherited Create;
FZoomIn := LeftButton;
FZoomOut := RightButton;
end;
procedure TGmOptions.SetZoomIn(AUserAction: TGmUserAction);
begin
if FZoomIn <> AUserAction then
begin
FZoomIn := AUserAction;
end;
end;
procedure TGmOptions.SetZoomOut(AUserAction: TGmUserAction);
begin
if FZoomOut <> AUserAction then
begin
FZoomOut := AUserAction;
end;
end;
//------------------------------------------------------------------------------
// *** TGmPreview ***
constructor TGmPreview.Create(AOwner: TComponent);
begin
FPreviewState := gmCreating;
inherited Create(AOwner);
FMessagesEnabled := False;
FZoom := DEFAULT_ZOOM;
FPaperSize := A4;
FBorderStyle := bsSingle;
FPages := TGmPageList.Create(Self);
FCurrentPage := 1;
FCanvas := TGmCanvas.Create(Self);
FCanvas.Page := FPages.AddPage;
FFooter := TGmFooter.Create(Self);
FHeader := TGmHeader.Create(Self);
FMargins := TGmMargins.Create(Self);
FOptions := TGmOptions.Create;
FPageImage := TGmPageImage.Create(Self);
FMargins.FPaintBox := FPageImage;
FPageImage.Margins := FMargins;
FPageImage.Parent := Self;
FPageImage.OnMouseMove := Self.OnMouseMove;
FPrintBorder := TGmValue.Create;
FPrintCopies := 1;
FPageHeight := TGmValue.Create;
FPageWidth := TGmValue.Create;
FPageHeight.AsMillimeters := 297;
FPageWidth.AsMillimeters := 210;
FPrinter := TGmPrinter.Create(Self);
FRegisteredComponents := TList.Create;
FZoomIncrement := 10;
Ctl3D := True;
Width := 220;
Height := 286;
{$IFNDEF VER100}
HorzScrollBar.Size := 16;
VertScrollBar.Size := 16;
{$ENDIF}
FMaxZoom := 400;
FMinZoom := 10;
FMessagesEnabled := True;
FPreviewState := gmIdle;
FPageImage.Scale := FZoom / 100;
end;
procedure TGmPreview.CreateParams(var Params: TCreateParams);
const
BorderStyles: array[TBorderStyle] of DWORD = (0, WS_BORDER);
begin
inherited CreateParams(Params);
with Params do
begin
Style := Style or BorderStyles[FBorderStyle];
if NewStyleControls and Ctl3D and (FBorderStyle = bsSingle) then
begin
Style := Style and not WS_BORDER;
ExStyle := ExStyle or WS_EX_CLIENTEDGE;
end;
end;
end;
destructor TGmPreview.Destroy;
begin
FPreviewState := gmDestroying;
FCanvas.Free;
FFooter.Free;
FHeader.Free;
FMargins.Free;
FOptions.Free;
FPages.Free;
FPrinter.Free;
FPrintBorder.Free;
FPageHeight.Free;
FPageWidth.Free;
FRegisteredComponents.Free;
FPreviewState := gmIdle;
inherited Destroy;
end;
procedure TGmPreview.Loaded;
begin
inherited Loaded;
if Assigned(FOnPageChange) then FOnPageChange(Self, FCurrentPage);
end;
procedure TGmPreview.MessageToControls(AMessage: integer; Param1, Param2: integer);
var
ICount: integer;
begin
if FMessagesEnabled then
begin
SendMessage(Self.Handle, AMessage, Param1, Param2);
for ICount := 0 to FRegisteredComponents.Count-1 do
TControl(FRegisteredComponents[ICount]).Perform(AMessage, Param1, Param2);
end;
end;
procedure TGmPreview.CMMouseLeave (var Message: TMessage);
begin
StopPanning;
end;
procedure TGmPreview.MouseMove(Shift: TShiftState; X, Y: Integer);
var
VertSBSize: integer;
HorzSBSize: integer;
begin
FMousePos.X := X;
FMousePos.Y := Y;
if FPanning then
begin
HorzScrollBar.Position := FPanningXYStart.X - FMousePos.X;
VertScrollBar.Position := FPanningXYStart.Y - FMousePos.Y;
end;
{$IFNDEF VER100}
VertSBSize := VertScrollBar.Size;
HorzSBSize := HorzScrollBar.Size;
{$ELSE}
VertSBSize := 18;
HorzSBSize := 18;
{$ENDIF}
if X > (Width-4) - VertSBSize then
StopPanning;
if Y > (Height-4) - HorzSBSize then
StopPanning;
inherited;
end;
procedure TGmPreview.SetParent(AParent: TWinControl);
begin
inherited SetParent(AParent);
if Assigned(AParent) then UpdatePreview;
end;
procedure TGmPreview.PositionPage;
var
ScrollBarX: Extended;
ScrollBarY: Extended;
RangeX,
RangeY: integer;
begin
// Get the current scrollbar values...
RangeX := (HorzScrollBar.Range-Width);
RangeY := (VertScrollBar.Range-Height);
ScrollBarX := 0;
ScrollBarY := 0;
if RangeX > 0 then ScrollBarX := HorzScrollBar.Position / RangeX;
if RangeY > 0 then ScrollBarY := VertScrollBar.Position / RangeY;
if FPageImage.Width > Width then
begin
HorzScrollBar.Visible := True;
HorzScrollBar.Position := Round((HorzScrollBar.Range - Width)*ScrollBarX);
end
else
begin
HorzScrollBar.Position := 0;
HorzScrollBar.Visible := False;
FPageImage.Left := 0;
end;
if FPageImage.Height > Height then
begin
VertScrollBar.Visible := True;
VertScrollBar.Position := Round((VertScrollBar.Range - Height)*ScrollBarY);
end
else
begin
VertScrollBar.Position := 0;
VertScrollBar.Visible := False;
FPageImage.Top := 0;
end;
CenterPage;
end;
procedure TGmPreview.PreviewResize(var Message: TMessage);
begin
inherited;
CenterPage;
end;
procedure TGmPreview.UpdateMessage(var Message: TMessage);
begin
UpdatePreview;
end;
procedure TGmPreview.MarginsChanged(var Message: TMessage);
begin
UpdatePreview;
end;
{procedure TGmPreview.RegisterComponent(var Message: TMessage);
begin
FRegisteredComponents.Add(IntToStr(Message.WParam));
end;}
procedure TGmPreview.AddAssociatedComponent(AComponent: TComponent);
begin
if FRegisteredComponents.IndexOf(AComponent) = -1 then
FRegisteredComponents.Add(AComponent);
end;
procedure TGmPreview.RemoveAssociatedComponent(AComponent: TComponent);
begin
if FRegisteredComponents.IndexOf(AComponent) <> -1 then
FRegisteredComponents.Delete(FRegisteredComponents.IndexOf(AComponent));
end;
{procedure TGmPreview.UnRegisterComponent(var Message: TMessage);
begin
with FRegisteredComponents do
Delete(IndexOf(IntToStr(Message.WParam)));
end;}
function TGmPreview.GetFileVersion(AFileName: string): Extended;
var
//AStream: TGmExtStream;
AStream: TFileStream;
begin
Result := -1;
AStream := TFileStream.Create(AFileName, fmOpenRead);
try
try
AStream.Read(Result, SizeOf(Result));
except
ShowGmError(Self, CANT_READ_VERSION);
end;
finally
AStream.Free;
end;
{AStream := TGmExtStream.Create;
try
try
AStream.LoadFromFile(AFileName);
try
Result := AStream.ReadExtended;
except
ShowGmError(Self, CANT_READ_VERSION);
end;
except
ShowGmError(Self, CANT_OPEN_FILE);
end;
finally
AStream.Free;
end; }
end;
function TGmPreview.Tokenize(AText: string; APage: integer): string;
var
tokenPosition: integer;
begin
Result := AText;
// search and replace the {DATE} token...
while Pos('{DATE}', Result) <> 0 do
begin
tokenPosition := Pos('{DATE}', Result);
Delete(Result, tokenPosition, 6);
Insert(FormatDateTime('dd-mmm-yyyy',Date), Result, tokenPosition);
end;
// search and replace the {TIME} token...
while Pos('{TIME}', Result) <> 0 do
begin
tokenPosition := Pos('{TIME}', Result);
Delete(Result, tokenPosition, 6);
Insert(FormatDateTime('hh:nn',Time), Result, tokenPosition);
end;
// search and replace the {PAGE} token...
while Pos('{PAGE}', Result) <> 0 do
begin
tokenPosition := Pos('{PAGE}', Result);
Delete(Result, tokenPosition, 6);
Insert(IntToStr(APage), Result, tokenPosition);
end;
// search and replace the {NUMPAGES} token...
while Pos('{NUMPAGES}', Result) <> 0 do
begin
tokenPosition := Pos('{NUMPAGES}', Result);
Delete(Result, tokenPosition, 10);
Insert(IntToStr(NumPages), Result, tokenPosition);
end;
end;
procedure TGmPreview.CenterOnClick(x, y: integer);
var
CenterPoint: TPoint;
begin
CenterPoint.X := Width div 2;
CenterPoint.Y := Height div 2;
HorzScrollBar.Position := HorzScrollBar.Position + (x - CenterPoint.X);
VertScrollBar.Position := VertScrollBar.Position + (y - CenterPoint.y);
end;
procedure TGmPreview.Clear;
var
ICount: integer;
PageChanged: Boolean;
ATempValue: Boolean;
begin
//if FP
PageChanged := FCurrentPage > 1;
ATempValue := FMessagesEnabled;
FMessagesEnabled := False;
for ICount := NumPages downto 1 do
DeletePage(ICount);
//Application.ProcessMessages;
FMessagesEnabled := ATempValue;
MessageToControls(GM_PREVIEW_CLEARED, 0, 0);
if PageChanged then MessageToControls(GM_PAGE_CHANGED, 1, 0);
FPageImage.Invalidate;
end;
procedure TGmPreview.DeleteCurrentPage;
begin
DeletePage(FCurrentPage);
end;
procedure TGmPreview.DeletePage(APage: integer);
begin
if NumPages > 1 then
FPages.DeletePage(APage) else
if NumPages = 1 then
FPages.Page[APage].Clear;
if FCurrentPage > NumPages then
SetCurrentPage(NumPages)
else
SetCurrentPage(FCurrentPage);
MessageToControls(GM_NUMPAGES_CHANGED, FPages.Count, 0);
MessageToControls(GM_UPDATE_PREVIEW, FPages.Count, 0);
end;
procedure TGmPreview.FirstPage;
begin
CurrentPage := 1;
end;
procedure TGmPreview.FitHeight;
begin
SetZoom(GetFitHeightZoom);
end;
procedure TGmPreview.FitWidth;
begin
SetZoom(GetFitWidthZoom);
end;
procedure TGmPreview.FitWholePage;
begin
SetZoom(MinInt(GetFitHeightZoom, GetFitWidthZoom));
end;
procedure TGmPreview.LastPage;
begin
CurrentPage := NumPages;
end;
function TGmPreview.NewPage: TGmPage;
begin
//UpdatePreview;
//FCanvas.FPage.DrawPage;
//FCanvas.FPage.DrawPage(InchWidth, InchHeight);
FCanvas.FPage := FPages.AddPage;
MessageToControls(GM_NUMPAGES_CHANGED, FPages.Count, 0);
CurrentPage := FPages.Count;
Result := FCanvas.Page;
if Assigned(FOnNewPage) then FOnNewPage(Self);
end;
procedure TGmPreview.NextPage;
begin
if CurrentPage < NumPages then
CurrentPage := CurrentPage + 1;
end;
procedure TGmPreview.PrevPage;
begin
if CurrentPage > 1 then
CurrentPage := CurrentPage - 1;
end;
procedure TGmPreview.Print;
begin
PrintRange(1, NumPages);
end;
procedure TGmPreview.PrintRange(AStartPage, AEndPage: integer);
function GetPageRect(Pps: TGmPagesPerSheet; PrnRect: TRect; PageNum: integer): TRect;
begin
case PagesPerSheet of
gmOnePage:
begin
Result := PrnRect;
end;
gmTwoPage:
begin
if FOrientation = gmPortrait then
begin
case PageNum mod 2 of
1: Result := Rect(PrnRect.Left, PrnRect.Top, PrnRect.Right div 2, PrnRect.Bottom);
0: Result := Rect(PrnRect.Right div 2, PrnRect.Top, PrnRect.Right, PrnRect.Bottom);
end;
end
else
begin
case PageNum mod 2 of
1: Result := Rect(PrnRect.Left, PrnRect.Top, PrnRect.Right, PrnRect.Bottom div 2);
0: Result := Rect(PrnRect.Left, PrnRect.Bottom div 2, PrnRect.Right, PrnRect.Bottom);
end;
end;
end;
gmFourPage:
begin
case PageNum mod 4 of
1: Result := Rect(PrnRect.Left, PrnRect.Top, PrnRect.Right div 2, PrnRect.Bottom div 2);
2: Result := Rect(PrnRect.Right div 2, PrnRect.Top, PrnRect.Right, PrnRect.Bottom div 2);
3: Result := Rect(PrnRect.Left, PrnRect.Bottom div 2, PrnRect.Right div 2, PrnRect.Bottom);
0: Result := Rect(PrnRect.Right div 2, PrnRect.Bottom div 2, PrnRect.Right, PrnRect.Bottom);
end;
end;
end;
end;
function CheckForNewPage(Pps: TGmPagesPerSheet; PageNum, NumPages: integer): boolean;
begin
Result := PageNum < NumPages;
case Pps of
gmTwoPage : Result := (PageNum mod 2 = 0) and (PageNum < NumPages);
gmFourPage: Result := (PageNum mod 4 = 0) and (PageNum < NumPages);
end;
end;
function SwapOrientation: Boolean;
begin
case Printer.Orientation of
poPortrait : Printer.Orientation := poLandscape;
poLandscape : Printer.Orientation := poPortrait;
end;
Result := True;
end;
procedure SwapValues(var Val1, Val2: integer);
var
TempVal: integer;
begin
TempVal := Val1;
Val1 := Val2;
Val2 := TempVal;
end;
var
IPageCount: integer;
IPrintedCount: integer;
ICopyCount: integer;
IObjectCount: integer;
APage: TGmPage;
PageRect,
PrinterRect: TRect;
AScale: Extended;
PW, PH: integer;
Offset: TPoint;
OrientationChanged: Boolean;
begin
if Assigned(FBeforePrint) then FBeforePrint(Self);
// Multiple orientation reports only support 1 Page-per-sheet printing...
if GetOrientationType = gmMixedOrientation then FPagesPerSheet := gmOnePage;
OrientationChanged := False;
Offset.x := GetDeviceCaps(Printer.Handle, PHYSICALOFFSETX);
Offset.y := GetDeviceCaps(Printer.Handle, PHYSICALOFFSETY);
PW := GetDeviceCaps(Printer.Handle, PHYSICALWIDTH);
PH := GetDeviceCaps(Printer.Handle, PHYSICALHEIGHT);
AScale := 1;
PrinterRect.Left := 0;
PrinterRect.Top := 0;
IPrintedCount := 0;
case PagesPerSheet of
gmOnePage, gmFourPage :
begin
if ((FOrientation = gmLandscape) and (Printer.Orientation = poPortrait)) or
((FOrientation = gmPortrait) and (Printer.Orientation = poLandscape)) then
begin
OrientationChanged := SwapOrientation;
SwapValues(PW, PH);
end;
// set the page scale for 4 pages per sheet...
if PagesPerSheet = gmFourPage then AScale := 0.5;
end;
gmTwoPage :
begin
if ((FOrientation = gmLandscape) and (Printer.Orientation <> poPortrait)) or
((FOrientation = gmPortrait) and (Printer.Orientation <> poLandscape)) then
begin
OrientationChanged := SwapOrientation;
SwapValues(PW, PH);
end;
// set the page scale for 4 pages per sheet...
AScale := MinInt(PW, PH) / MaxInt(PW, PH);
end;
end;
PrinterRect.Right := PW;
PrinterRect.Bottom := PH;
GmPrinter.BeginDoc(FPrintFile);
for ICopyCount := 1 to FPrintCopies do
try
for IPageCount := AStartPage to AEndPage do
begin
APage := Pages[IPageCount];
if Assigned(FBeforePrintPage) then
FBeforePrintPage(Self, APage, Printer.Handle);
PageRect := GetPageRect(PagesPerSheet, PrinterRect, IPageCount);
PageRect.Left := PageRect.Left - FPrinter.GetOffset.X;
PageRect.Top := PageRect.Top - FPrinter.GetOffset.Y;
PageRect.Right := PageRect.Right - FPrinter.GetOffset.X;
PageRect.Bottom := PageRect.Bottom - FPrinter.GetOffset.Y;
if Header.Visible then
Header.Draw(GmPrinter.Canvas, FMargins, PageRect, IPageCount, AScale);
if Footer.Visible then
Footer.Draw(GmPrinter.Canvas, FMargins, PageRect, IPageCount, AScale);
for IObjectCount := 0 to FPages.Page[IPageCount].Count-1 do
begin
TGmBaseObject(APage.GmObject[IObjectCount]).Draw(GmPrinter.Canvas, Self, Point(0-PageRect.Left, 0-PageRect.Top), AScale);
end;
if CheckForNewPage(PagesPerSheet, IPageCount, AEndPage) then
begin
GmPrinter.NewPage(Pages[IPageCount+1].Orientation);
if Pages[IPageCount].Orientation <> Pages[IPageCount+1].Orientation then
begin
SwapValues(PrinterRect.Right, PrinterRect.Bottom);
end;
end;
Inc(IPrintedCount);
if Assigned(FOnPrintProgress) then FOnPrintProgress(Self, IPrintedCount, 1+(AEndPage-AStartPage));
end
finally
GmPrinter.EndDoc;
FPrintFile := '';
//if PagesPerSheet = gmTwoPage then SwapOrientation;
if OrientationChanged then SwapOrientation;
if Assigned(FAfterPrint) then FAfterPrint(Self);
end;
end;
procedure TGmPreview.PrintCurrentPage;
begin
PrintRange(FCurrentPage, FCurrentPage);
end;
procedure TGmPreview.PrintToFile(AFileName: string);
begin
FPrintFile := AFileName;
PrintRange(FCurrentPage, FCurrentPage);
end;
//------------------------------------------------------------------------------
// File/Stream Saving/Loading routines...
procedure TGmPreview.LoadFromFile(AFilename: string);
var
AFileStream: TFileStream;
AFileVersion: Extended;
begin
AFileStream := TFileStream.Create(AFileName, fmOpenRead);
try
AFileStream.Read(AFileVersion, SizeOf(AFileVersion));
if AFileVersion < 2.3 then
// use the old load method...
LoadFromStreamOld(Self, AFileStream)
else
begin
// the current method...
AFileStream.Seek(0, soFromBeginning);
LoadFromStream(AFileStream);
end;
finally
AFileStream.Free;
end;
end;
procedure TGmPreview.SaveToFile(AFilename: string);
var
AFileStream: TFileStream;
begin
AFileStream := TFileStream.Create(AFileName, fmCreate);
try
SaveToStream(AFileStream);
finally
AFileStream.Free;
end;
end;
procedure TGmPreview.LoadFromStream(AStream: TStream);
var
AFileVersion: Extended;
GmStream: TGmExtStream;
ICount: integer;
APage: TGmPage;
LoadFile: Boolean;
begin
MessageToControls(GM_LOADING, 0, 0);
AStream.ReadBuffer(AFileVersion, SizeOf(AFileVersion));
GmStream := TGmExtStream.Create;
try
Clear;
if Assigned(FBeforeReadStream) then FBeforeReadStream(Self, GmStream);
GmStream.LoadFromStream(AStream);
//AFileVersion := GmStream.ReadExtended;
LoadFile := True;
if Assigned(FBeforeLoad) then FBeforeLoad(Self, AFileVersion, LoadFile);
if LoadFile = False then Exit;
LoadDocInfoFromStream(GmStream);
LoadPageSetupFromStream(GmStream);
Margins.LoadFromStream(GmStream);
FHeader.LoadFromStream(GmStream);
Footer.LoadFromStream(GmStream);
for ICount := 1 to FNumPages do
begin
if ICount = 1 then APage := FPages.Page[1] else APage := NewPage;
APage.LoadFromStream(GmStream);
if Assigned(FOnLoadProgress) then FOnLoadProgress(Self, Round(ICount/FNumPages*100));
end;
finally
GmStream.Free;
end;
MessageToControls(GM_LOADING, 1, 0);
MessageToControls(GM_UPDATE_PREVIEW, 0, 0);
end;
procedure TGmPreview.SaveToStream(AStream: TStream);
var
GmStream: TGmExtStream;
ICount: integer;
AVersion: Extended;
begin
AVersion := SUITE_VERSION;
AStream.WriteBuffer(AVersion, SizeOf(AVersion));
GmStream := TGmExtStream.Create;
try
//GmStream.WriteExtended(SUITE_VERSION);
SaveDocInfoToStream(GmStream);
SavePageSetupToStream(GmStream);
Margins.SaveToStream(GmStream);
FHeader.SaveToStream(GmStream);
FFooter.SaveToStream(GmStream);
for ICount := 1 to NumPages do
begin
FPages.Page[ICount].SaveToStream(GmStream);
if Assigned(FOnSaveProgress) then FOnSaveProgress(Self, Round(ICount/FNumPages*100));
end;
finally
if Assigned(FBeforeWriteStream) then FBeforeWriteStream(Self, GmStream);
GmStream.SaveToStream(AStream);
GmStream.Free;
end;
end;
procedure TGmPreview.LoadPageSetupFromStream(AStream: TStream);
var
GmStream: TGmExtStream;
begin
GmStream := TGmExtStream.Create;
try
GmStream.LoadFromStream(AStream);
FPageWidth.AsUnits := GmStream.ReadInteger;
FPageHeight.AsUnits := GmStream.ReadInteger;
FPaperSize := StrToPaperSize(GmStream.ReadStr);
FOrientation := TGmOrientation(GmStream.ReadInteger);
Shadow.Color := GmStream.ReadInteger;
Shadow.Width := GmStream.ReadInteger;
MessageToControls(GM_PAPER_SIZE_CHANGED, 0, 0);
MessageToControls(GM_ORIENTATION_CHANGED, 0, 0);
finally
GmStream.Free;
end;
end;
procedure TGmPreview.SavePageSetupToStream(AStream: TStream);
var
GmStream: TGmExtStream;
begin
GmStream := TGmExtStream.Create;
try
GmStream.WriteInteger(FPageWidth.AsUnits);
GmStream.WriteInteger(FPageHeight.AsUnits);
GmStream.WriteStr(PaperSizeToStr(FPaperSize));
GmStream.WriteInteger(Ord(Orientation));
GmStream.WriteInteger(Shadow.Color);
GmStream.WriteInteger(Shadow.Width);
finally
GmStream.SaveToStream(AStream);
GmStream.Free;
end;
end;
procedure TGmPreview.LoadDocInfoFromStream(AStream: TStream);
var
GmStream: TGmExtStream;
begin
GmStream := TGmExtStream.Create;
try
GmStream.LoadFromStream(AStream);
GmStream.ReadDateTime;
FNumPages := GmStream.ReadInteger;
finally
GmStream.Free;
end;
end;
procedure TGmPreview.SaveDocInfoToStream(AStream: TStream);
var
GmStream: TGmExtStream;
begin
GmStream := TGmExtStream.Create;
try
// the two following values aren't used yet... but I thought they may be
// needed at a later time.
GmStream.WriteDateTime(Now);
GmStream.WriteInteger(NumPages);
finally
GmStream.SaveToStream(AStream);
GmStream.Free;
end;
end;
// End of File/Stream Saving/Loading routines
//------------------------------------------------------------------------------
procedure TGmPreview.ScrollToPosition(XPercent, YPercent: Extended);
begin
HorzScrollBar.Position := Round((XPercent/100) * (HorzScrollBar.Range-(ClientWidth)));
VertScrollBar.Position := Round((YPercent/100) * (VertScrollBar.Range-(ClientHeight)));
//if XPercent <> -1 then HorzScrollBar.Position := Round((HorzScrollBar.Range / 100) * XPercent);
// if YPercent <> -1 then VertScrollBar.Position := Round((VertScrollBar.Range / 100) * YPercent);
end;
procedure TGmPreview.SetCursor(ACursor: TGmCursor);
begin
case ACursor of
gmDefault : Screen.Cursor := crDefault;
gmZoomIn : Screen.Cursor := crZoomIn;
gmZoomOut : Screen.Cursor := crZoomOut;
end;
end;
procedure TGmPreview.SetPageSize(AWidth, AHeight: Extended; AUnits: TGmMeasurement);
begin
FPaperSize := Custom;
FPageWidth.AsUnits := Round(ConvertValue(AWidth, AUnits, GmUnits));
FPageHeight.AsUnits := Round(ConvertValue(AHeight, AUnits, GmUnits));
if Assigned(FOnPageSizeChange) then FOnPageSizeChange(Self);
end;
procedure TGmPreview.StartPanning;
begin
FPanning := True;
FPanningXYStart.X := FMousePos.X + HorzScrollBar.Position;
FPanningXYStart.Y := FMousePos.Y + VertScrollBar.Position;
Screen.Cursor := crHandPoint;
end;
procedure TGmPreview.StopPanning;
begin
FPanning := False;
Screen.Cursor := crDefault;
end;
procedure TGmPreview.UpdatePreview;
var
AWidth, AHeight: Integer;
InchWidth, InchHeight: Extended;
APage: TGmPage;
begin
if FPaperSize <> Custom then
GetPaperSize(FPaperSize, AWidth, AHeight, Canvas.Page.Orientation)
else
begin
// if it is a custom page size... work out the dimensions...
if Canvas.Page.Orientation = gmPortrait then
begin
AWidth := MinInt(FPageWidth.AsUnits, FPageHeight.AsUnits);
AHeight := MaxInt(FPageWidth.AsUnits, FPageHeight.AsUnits);
end
else
begin
AWidth := MaxInt(FPageWidth.AsUnits, FPageHeight.AsUnits);
AHeight := MinInt(FPageWidth.AsUnits, FPageHeight.AsUnits);
end;
end;
InchWidth := ConvertValue(AWidth, GmUnits, GmInches);
InchHeight := ConvertValue(AHeight, GmUnits, GmInches);
FPageImage.WidthInches := InchWidth;
FPageImage.HeightInches := InchHeight;
APage := FPages.Page[FCurrentPage];
APage.FInchWidth := InchWidth;
APage.FInchHeight := InchHeight;
APage.DrawPage;//(InchWidth, InchHeight);
FCanvas.Page := APage;
FPageImage.SetPageMetafile(APage.Metafile, FMessagesEnabled);
MessageToControls(GM_PREVIEW_UPDATED, NumPages, 0);
//SendMessage(Self.Handle, WM_SIZE, 0, 0);
//MessageToControls(WM_SIZE, 0, 0);
Application.ProcessMessages;
end;
procedure TGmPreview.UsePrinterPageSize;
begin
if FPrinter.PrinterSelected then
begin
SetPageSize(FPrinter.PrinterWidth.AsUnits, FPrinter.PrinterHeight.AsUnits, GmUnits);
MessageToControls(GM_UPDATE_PREVIEW, 0, 0);
end;
end;
procedure TGmPreview.ZoomIn;
begin
case FZoomStyle of
gmFixedZoom : SetZoom(FZoom + FZoomIncrement);
gmVariableZoom: SetZoom(FZoom + (FZoom div 2));
end;
end;
procedure TGmPreview.ZoomOut;
begin
case FZoomStyle of
gmFixedZoom : SetZoom(FZoom - FZoomIncrement);
gmVariableZoom: SetZoom(FZoom - (FZoom div 2));
end;
end;
function TGmPreview.GetPage(APage: integer): TGmPage;
begin
Result := FPages.Page[APage];
end;
function TGmPreview.GetPrinterBinIndex: integer;
begin
Result := FPrinter.PrinterBinIndex;
end;
function TGmPreview.GetPrinterBins: TStrings;
begin
Result := FPrinter.PrinterBins;
end;
function TGmPreview.GetPrinterIndex: integer;
begin
Result := FPrinter.PrinterIndex;
end;
function TGmPreview.GetPrinters: TStrings;
begin
Result := FPrinter.FPrinterNames;
end;
function TGmPreview.GetShadow: TGmShadow;
begin
Result := FPageImage.Shadow;
end;
function TGmPreview.GetPrintTitle: string;
begin
Result := FPrinter.Title;
end;
function TGmPreview.GetVersion: Extended;
begin
Result := SUITE_VERSION;
end;
function TGmPreview.PaperSizeToStr(APaperSize: TGmPaperSize): string;
begin
case APaperSize of
A4 : Result := 'A4';
A5 : Result := 'A5';
else
Result := 'Custom';
end;
end;
function TGmPreview.StrToPaperSize(APaperStr: string): TGmPaperSize;
begin
if APaperStr = 'A4' then Result := A4 else
if APaperStr = 'A5' then Result := A5 else
Result := Custom;
end;
function TGmPreview.GetCoordsRelative: TGmCoordsRelative;
begin
Result := FCanvas.CoordsRelativeTo;
end;
function TGmPreview.GetFitHeightZoom: integer;
var
AScale: Extended;
begin
AScale := (Height-2*FPageImage.Gutter) / (FPageImage.HeightInches*ScreenPpi);
Result := Trunc(AScale * 100);
end;
function TGmPreview.GetFitWidthZoom: integer;
var
AScale: Extended;
begin
AScale := (Width-(2*FPageImage.Gutter)) / (FPageImage.WidthInches*ScreenPpi);
Result := Trunc(AScale * 100);
end;
function TGmPreview.GetMetaFile(APage: integer): TMetafile;
begin
Result := FPages.Page[APage].Metafile;
end;
function TGmPreview.GetNumPages: integer;
begin
Result := FPages.Count;
end;
function TGmPreview.GetOrientationType: TGmOrientationType;
var
ICount: integer;
begin
if FOrientation = GmPortrait then
Result := gmPortraitReport
else
Result := gmLandscapeReport;
for ICount := 1 to GetNumPages do
if Pages[ICount].Orientation <> FOrientation then Result := gmMixedOrientation;
end;
procedure TGmPreview.CenterPage;
begin
if FPageImage.Height < Height then FPageImage.Top := (Height - FPageImage.Height-8) div 2;
if FPageImage.Width < Width then FPageImage.Left := (Width - FPageImage.Width-8) div 2;
if (FPageImage.Height > Height) and (FPageImage.Top > 0) then FPageImage.Top := 0;
if (FPageImage.Width > Width) and (FPageImage.Left > 0) then FPageImage.Left := 0;
end;
procedure TGmPreview.SetBorderStyle(AStyle: TBorderStyle);
begin
if FBorderStyle <> AStyle then
begin
FBorderStyle := AStyle;
RecreateWnd;
end;
end;
procedure TGmPreview.SetCoordsRelative(ACoordsRelative: TGmCoordsRelative);
begin
FCanvas.CoordsRelativeTo := ACoordsRelative;
end;
procedure TGmPreview.SetCurrentPage(APage: integer);
//var
//LastPage: integer;
begin
if (APage <> FCurrentPage) then
begin
//LastPage := APage;
FCurrentPage := APage;
Canvas.Page := Pages[APage];
if Assigned(FOnPageChange) then FOnPageChange(Self, APage);
UpdatePreview;
MessageToControls(GM_PAGE_CHANGED, APage, 0);
end;
end;
procedure TGmPreview.SetGutter(AGutter: integer);
begin
if AGutter <> FGutter then
begin
FGutter := AGutter;
FPageImage.Gutter := FGutter;
end;
end;
procedure TGmPreview.SetOrientation(AOrientation: TGmOrientation);
var
ICount: integer;
TempValue: integer;
TempBoolean: Boolean;
begin
if FOrientation <> AOrientation then
begin
TempValue := PageHeight.AsUnits;
PageHeight.AsUnits := PageWidth.AsUnits;
PageWidth.AsUnits := TempValue;
FOrientation := AOrientation;
if Assigned(FOnChangeOrientation) then FOnChangeOrientation(Self);
TempBoolean := FMessagesEnabled;
FMessagesEnabled := False;
for ICount := 1 to NumPages do FPages.Page[ICount].Orientation := AOrientation;
UpdatePreview;
PositionPage;
FMessagesEnabled := TempBoolean;
MessageToControls(GM_ORIENTATION_CHANGED, 0, 0);
end;
end;
procedure TGmPreview.SetPagesPerSheet(APagesPerSheet: TGmPagesPerSheet);
begin
FPagesPerSheet := APagesPerSheet;
MessageToControls(GM_MULTIPAGE_CHANGED, 0, 0);
end;
procedure TGmPreview.SetPaperSize(APaperSize: TGmPaperSize);
var
w, h: integer;
begin
FPaperSize := APaperSize;
if APaperSize <> Custom then
begin
GetPaperSize(FPaperSize, w, h, FOrientation);
MessagesEnabled := False;
FPageWidth.AsUnits := w;
FPageHeight.AsUnits := h;
MessagesEnabled := True;
MessageToControls(GM_UPDATE_PREVIEW, 0, 0);
MessageToControls(GM_PAPER_SIZE_CHANGED, 0, 0);
end;
end;
procedure TGmPreview.SetPrintCopies(APrintCopies: integer);
begin
if (APrintCopies <> FPrintCopies) and (APrintCopies > 0) then
FPrintCopies := APrintCopies;
end;
procedure TGmPreview.SetPrinterBinIndex(AIndex: integer);
begin
FPrinter.PrinterBinIndex := AIndex;
end;
procedure TGmPreview.SetPrinterIndex(AIndex: integer);
begin
FPrinter.PrinterIndex := AIndex;
end;
procedure TGmPreview.SetPrintTitle(ATitle: string);
begin
FPrinter.Title := ATitle;
end;
procedure TGmPreview.SetZoom(AZoom: integer);
var
PercentX: Extended;
PercentY: Extended;
begin
if (AZoom > 0) then
begin
if Assigned(FOnZoom) then FOnZoom(Self, FZoom, AZoom);
FZoom := AZoom;
PercentX := 0;
PercentY := 0;
if HorzScrollBar.Position > 0 then
PercentX := ((HorzScrollBar.Position) /(HorzScrollBar.Range-(ClientWidth))) * 100;
if VertScrollBar.Position > 0 then
PercentY := ((VertScrollBar.Position) /(VertScrollBar.Range-(ClientHeight))) *100;
//F/PageImage.Visible := False;
FPageImage.Scale := FZoom/100;
MessageToControls(GM_UPDATE_PREVIEW, 0, 0);
if HasParent then
PositionPage;
ScrollToPosition(PercentX, PercentY);
//FPageImage.Visible := True;
end;
end;
end.